6

我正在研究一些应该在 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

我从来没有见过这样的事情,所以我不确定这是否普遍。是否不鼓励这样做?可能的缺点是什么?

4

1 回答 1

4

因此,正如我在评论中提到的,我看到这种方法存在三个问题。

首先,如果任何实体应该共享两种语言之间的链接,它就不允许库与混合 C/C++ 翻译一起使用。如果头文件包含在 C 翻译单元和 C++ 翻译单元中,则所有声明的实体将具有不同的名称,有前缀或没有前缀。所以实际上它会像两个独立的库一样工作,一个用于 C 翻译单元,一个用于 C++ 翻译单元。如果任何图书馆实体应该在翻译单元之间共享链接,它将不起作用。

其次,extern "C"在命名空间内将正确地在 C++ 代码的命名空间内限定名称。但是,为了保证 C 链接,必须将不带命名空间前缀的名称引入全局 C 命名空间,从而将其与大量不带库前缀的名称混为一谈。

第三,编写在 C 和 C++ 之间也可以转换的用户代码变得很困难。任何此类用户都必须引入类似的宏。

如果该库不应该在混合 C/C++ 代码中使用(或没有任何共享链接),那么extern "C"是不必要的,在删除它之后,我认为这种方法可能没问题。

于 2019-10-17T06:04:15.633 回答