Я знаю вопросы относительно extern "C"
меня уже спрашивали, но я получаю смешанные сигналы и хотел бы, чтобы кто-нибудь указал мне, что лучше всего делать в сценарии ниже. Я написал драйвер для Linux и имею несколько struct
определены, а также некоторые _IO
, _IOR
, а также _IOW
определения для ioctl(...)
звонки. Ни одна из моих структур не содержит никаких функций, ниже приведен пример struct
, enum
а также ioctl
что я использую:
#ifdef __cplusplus
extern "C" {
#endif
enum Alignment
{
Left = 0,
Right = 1,
Middle = 3
};
struct Data
{
int Size;
void* Address;
};
#define foo _IOR(DRV_ID, 1, struct Data*);
#ifdef __cplusplus
}
#endif
Мой вопрос, мне нужно добавить extern "C"
в этот заголовок? Заголовок определен в моем драйвере, который написан на C и используется пользовательскими программами, написанными на C ++. Я понимаю, потому что нет никаких функций-членов или определенных вызовов библиотечных функций, которые мне не нужны extern "C"
,
Кроме того, безопасно ли изменить мой enum
ниже без extern "C"
:
#ifdef __cplusplus >= 201103L
enum class Alignment
#else
enum Alignment
#endif
{
Left = 0,
Right = 1,
Middle = 3
};
Мой заголовок уже завернут в extern "C"
, Я пытаюсь понять, нужно ли это для элементов, которые не вызывают функции и искажение имени является проблемой.
в стандарте C ++, extern "C"
влияет только: типы функций, имена функций и имена переменных. Не для enum
определения.
Ваш компилятор может сделать что-то помимо того, что говорит стандарт, вам придется ознакомиться с его документацией.
Условный enum class
плохая идея Вы могли бы в конечном итоге с enum
размер в C отличается от размера в C ++, что приводит к проблемам с совместимостью. Это не охватывается ни одним из стандартов, но для совместимости было бы лучше убедиться, что один и тот же код используется для обоих языков, кроме extern "C"
,
Здесь есть конфликт:
ваш код выглядит так:
#ifdef __cplusplus >= 201103L
enum class Alignment
#else
enum Alignment
но extern "c"
следует поставить в точном макросе:
#ifdef __cplusplus
extern "C"#endif
enum Alignment
результат, если вы добавите оба макроса:
extern "C" enum class Alignment
но это незаконно, поскольку язык C не знает таких, как объявление.
поэтому, я думаю, что если вы хотите использовать extern "C"
Чтобы иметь возможность использовать заголовок из c, а не только c ++, вы должны отказаться от enum class
и использовать старую моду enum
тип. если вы решите использовать заголовок только из c ++, extern "C"
не нужно, и вы можете использовать enum class
,
Перенос имени не важен для типов данных. То, что вы получаете из своей библиотеки — это чистые двоичные данные, и им все равно, как вы их называете. Для ваших типов важнее иметь правильное выравнивание и порядок.