При написании кода для печати следов на C ++ я натолкнулся на этот ответ, который включает в себя копирование определения типа:
/* This structure mirrors the one found in /usr/include/asm/ucontext.h */
typedef struct _sig_ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
} sig_ucontext_t;
Я не могу просто включить <asm/ucontext.h>
так как там это определяется как просто ucontext
который сталкивается с аналогично названным типом из <sys/ucontext.h>
(что входит из необходимого <signal.h>
):
/* Userlevel context. */
typedef struct ucontext
{
unsigned long int uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
__sigset_t uc_sigmask;
struct _libc_fpstate __fpregs_mem;
} ucontext_t;
Все, что мне нужно здесь, это struct sigcontext uc_mcontext
член от asm
версия. Есть ли лучший способ получить это значение, чем просто скопировать эту структуру? Это кажется невероятно хакерским и подверженным ошибкам.
Один из возможных обходных путей — сделать asm/ucontext.h
первое включение в ваш исходный файл и препроцессор злоупотребления для переименования конфликтующего определения:
#define ucontext asm_ucontext
#include <asm/ucontext.h>
#undef asm_ucontext
Вы можете использовать asm_ucontext
сослаться на альтернативное определение ucontext
,
Немного менее хакерский подход — использовать sed для автоматического извлечения необходимых определений из системного файла:
$ echo '#include <asm/ucontext.h>' | gcc -x c - -E -o- | sed -n '/^struct ucontext/,/^};/{ s/ucontext/asm_ucontext/; p}' | tee asm_ucontext.h
struct asm_ucontext {
unsigned long uc_flags;
struct asm_ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
};