对非函数调用相关声明使用 "extern C"

Using "extern C" on non function call related declarations

本文关键字:extern 声明 函数调用      更新时间:2023-10-16

我知道以前有人问过关于extern "C"的问题,但我得到的信号很复杂,希望有人能告诉我下面场景中的最佳实践是什么。我已经为Linux编写了一个驱动程序,并为ioctl(...)调用定义了几个struct以及一些_IO, _IOR_IOW定义。我的结构中没有包含任何函数,下面是我使用的struct, enumioctl的示例:

#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是一个坏主意。最终,C中的enum的大小可能与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

名称混淆对于数据类型并不重要。你从库中得到的是纯二进制数据,它们不在乎你怎么命名它们。更重要的是要有正确的对齐和顺序。