Написание (прототип функции, указатель функции, внешний указатель) Меньше

Есть ли способ написать макрос или typedef с некоторой магией, чтобы я мог написать три строки ниже меньше?

extern "C" NTSTATUS NTAPI KeInitializeApc( PKAPC Apc, 
                                           PKTHREAD thread,
                                           UCHAR state_index,
                                           PKKERNEL_ROUTINE ker_routine,
                                           PKRUNDOWN_ROUTINE rd_routine,
                                           PKNORMAL_ROUTINE nor_routine,
                                           UCHAR mode,
                                           PVOID context );
typedef NTSTATUS (NTAPI *KeInitializeApc_t)( PKAPC Apc, 
                                             PKTHREAD thread,
                                             UCHAR state_index,
                                             PKKERNEL_ROUTINE ker_routine,
                                             PKRUNDOWN_ROUTINE rd_routine,
                                             PKNORMAL_ROUTINE nor_routine,
                                             UCHAR mode,
                                             PVOID context );
extern "C" KeInitializeApc_t PKeInitializeApc;

Кроме того, нужно ли использовать extern "C" для прототипа, функции и extern? Если я хочу неискаженные имена?

extern "C" NTSTATUS NTAPI KeInitializeApc( PKAPC Apc, 
                                           PKTHREAD thread,
                                           UCHAR state_index,
                                           PKKERNEL_ROUTINE ker_routine,
                                           PKRUNDOWN_ROUTINE rd_routine,
                                           PKNORMAL_ROUTINE nor_routine,
                                           UCHAR mode,
                                           PVOID context );
extern "C" typedef NTSTATUS (NTAPI *KeInitializeApc_t)( PKAPC Apc, 
                                                        PKTHREAD thread,
                                                        UCHAR state_index,
                                                        PKKERNEL_ROUTINE ker_routine,
                                                        PKRUNDOWN_ROUTINE rd_routine,
                                                        PKNORMAL_ROUTINE nor_routine,
                                                        UCHAR mode,
                                                        PVOID context );
extern "C" KeInitializeApc_t PKeInitializeApc;

Использование extern "C" в каждой строке не кажется правильным.

Спасибо за ваше время.


person DebugMechanic    schedule 15.07.2016    source источник


Ответы (3)


Если вы можете/разрешено использовать С++ 11, вы можете попробовать использовать decltype следующим образом:

extern "C" {
    NTSTATUS NTAPI KeInitializeApc( PKAPC Apc, 
                                    PKTHREAD thread,
                                    UCHAR state_index,
                                    PKKERNEL_ROUTINE ker_routine,
                                    PKRUNDOWN_ROUTINE rd_routine,
                                    PKNORMAL_ROUTINE nor_routine,
                                    UCHAR mode,
                                    PVOID context );

    using KeInitializeApc_t = decltype(&KeInitializeApc);
    KeInitializeApc_t PKeInitializeApc;
}

РЕДАКТИРОВАТЬ: я пропустил там тег c. Если вы хотите написать код так, чтобы он работал как для C, так и для C++, вы можете попробовать:

#ifdef __cplusplus
extern "C" {
#endif

typedef NTSTATUS NTAPI KeInitializeApc_f( PKAPC Apc, 
                                          PKTHREAD thread,
                                          UCHAR state_index,
                                          PKKERNEL_ROUTINE ker_routine,
                                          PKRUNDOWN_ROUTINE rd_routine,
                                          PKNORMAL_ROUTINE nor_routine,
                                          UCHAR mode,
                                          PVOID context );
KeInitializeApc_f KeInitializeApc;
typedef KeInitializeApc_f *KeInitializeApc_t;
KeInitializeApc_t PKeInitializeApc;

#ifdef __cplusplus
}
#endif
person Nikola Benes    schedule 15.07.2016

Вы можете сгруппировать свои определения в одном extern "C" следующим образом:

#ifdef __cplusplus
extern "C" {
#endif

NTSTATUS NTAPI KeInitializeApc( PKAPC Apc, 
                                           PKTHREAD thread,
                                           UCHAR state_index,
                                           PKKERNEL_ROUTINE ker_routine,
                                           PKRUNDOWN_ROUTINE rd_routine,
                                           PKNORMAL_ROUTINE nor_routine,
                                           UCHAR mode,
                                           PVOID context );
typedef NTSTATUS (NTAPI *KeInitializeApc_t)( PKAPC Apc, 
                                                        PKTHREAD thread,
                                                        UCHAR state_index,
                                                        PKKERNEL_ROUTINE ker_routine,
                                                        PKRUNDOWN_ROUTINE rd_routine,
                                                        PKNORMAL_ROUTINE nor_routine,
                                                        UCHAR mode,
                                                        PVOID context );
KeInitializeApc_t PKeInitializeApc;

#ifdef __cplusplus
}
#endif
person Brandon    schedule 15.07.2016

Есть ли способ написать макрос или typedef с некоторой магией, чтобы я мог написать три строки ниже меньше?

Возможно, вы ищете что-то вроде этого:

#define NTDECLARE(name, args) \
  extern "C" NTSTATUS NTAPI name args; \
  extern "C" typedef NTSTATUS (NTAPI * name ## _t) args; \
  extern name ## _t P ## name;

NTDECLARE(KeInitializeApc, ( PKAPC Apc, 
                             PKTHREAD thread,
                             UCHAR state_index,
                             PKKERNEL_ROUTINE ker_routine,
                             PKRUNDOWN_ROUTINE rd_routine,
                             PKNORMAL_ROUTINE nor_routine,
                             UCHAR mode,
                             PVOID context ) )

Макрос NTDECLARE можно, конечно, использовать для объявления других функций, типов, трио указателей с разными именами и, возможно, параметрами.

Кроме того, нужно ли использовать extern "C" для прототипа, функции и extern?

Вам не нужно применять extern "C" к объявлению указателя, но если код предназначен для заголовочного файла, вам, вероятно, понадобится обычный extern, как показано. Вы можете исключить extern "C" из всех отдельных объявлений и вместо этого поместить их все в блок extern "C" { ... }.

person John Bollinger    schedule 15.07.2016
comment
Спасибо, Джон, я воспользуюсь твоим ответом. Мне нравится макрос :) - person DebugMechanic; 15.07.2016