Составьте заголовочный файл C, чтобы его можно было использовать из C ++ - PullRequest
6 голосов
/ 17 октября 2019

Я работаю над заголовочным файлом библиотеки, который предполагается использовать как на C, так и на C ++. Поскольку C не имеет концепции пространства имен, я бы добавил «префикс библиотеки» ко всем именам, определенным в заголовочном файле. Для C ++, напротив, я бы определил пространство имен. Поэтому я сейчас думаю о дизайне как об этом:

mylib.h

#ifdef __cplusplus
namespace mylib{
#define NAME_PREFIX(identifier) identifier
extern "C" {
#else
#define NAME_PREFIX(identifier) mylib_identifier
#endif

int NAME_PREFIX(foo)(void);

//other declarations go here

#ifdef __cplusplus
} //extern "C"
} //namespace mylib
#endif

Я никогда не видел ничего подобного, поэтому я не уверен, что это распространено. Не рекомендуется ли это делать? Каковы возможные недостатки?

1 Ответ

4 голосов
/ 17 октября 2019

Итак, как я упоминал в комментариях, с этим подходом я вижу три проблемы:

Во-первых, он не позволяет использовать библиотеку со смешанным переводом C / C ++, если предполагается наличие каких-либо сущностей. поделиться связью между двумя языками. Если заголовочный файл включен в модуль перевода C и модуль перевода C ++, все объявленные объекты будут иметь разные имена, либо с префиксом, либо без него. Таким образом, в действительности все будет работать так, как если бы это были две отдельные библиотеки, одна использовалась в модуле перевода C, а другая в модуле перевода C ++. Если предполагается, что какие-либо библиотечные объекты совместно используют связь между единицами перевода, это не будет работать.

Во-вторых, extern "C" внутри пространства имен будет правильно охватывать имя внутри пространства имен для кода C ++. Однако, чтобы гарантировать связь C, имя без префикса пространства имен должно быть введено в глобальное пространство имен C, загромождая его множеством имен без префикса библиотеки.

В-третьих, это затрудняет написание кода пользователя. это должно быть переведено между C и C ++. Любой такой пользователь должен будет ввести похожий макрос.

Если не предполагается использовать библиотеку в смешанном коде C / C ++ (или без какой-либо общей ссылки), то extern "C" не требуется и после его удаленияЯ думаю, что подход может быть в порядке.

...