Как написать заголовочный файл C, который можно использовать в программах на С++?
Возможный дубликат:
Как проверить (через препроцессор), если исходный файл C скомпилирован как код на С++
Я пытаюсь найти стандартный макрос, который будет проверять, компилируется ли заголовочный файл как C или как С++. Цель этого заключается в том, что заголовок может быть включен кодом C или С++ и должен вести себя несколько иначе, в зависимости от того, какой. В частности:
В C мне нужно, чтобы это был код:
extern size_t insert (const char*);
В С++ мне нужно, чтобы это был код:
extern "C" size_t insert (const char*);
Кроме того, есть ли способ избежать размещения #ifdef вокруг каждого объявления в заголовке?
Ответы
Ответ 1
Это нормально, чтобы скопировать файлы заголовков C следующим образом, чтобы их можно было использовать в программах на С++. Проверьте файлы системного заголовка, такие как stdio.h, и вы, вероятно, увидите следующее:
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
Ответ 2
Ответ заключается в использовании макроса __cplusplus. В этом случае наиболее простой подход заключается в следующем:
extern
#ifdef __cplusplus
"C"
#endif
size_t insert (const char*);
Этот макрос является частью стандарта С++.
Ответ 3
Вам может показаться разумным определить три макроса, чтобы помочь с этим:
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#define EXTERN_C extern "C"
#else
#define EXTERN_C_BEGIN /* Nothing */
#define EXTERN_C_END /* Nothing */
#define EXTERN_C extern /* Or Nothing */
#endif /* __cplusplus */
Это будет наиболее полезно в стандартном заголовке, который включен в большинство мест вашего проекта. Для одной функции вы можете написать:
EXTERN_C size_t insert(const char *name);
Для группы функций вы можете написать:
EXTERN_C_BEGIN
size_t other_insert(const char *name);
size_t other_delete(const char *name);
size_t other_update(const char *old_name, const char *new_name);
EXTERN_C_END
Допускается включать extern
перед отдельными функциями внутри блока EXTERN_C_BEGIN
to EXTERN_C_END
.