这在 C 或 C++ 中如何工作?
extern "C" {
#include <unistd.h>
#include <fd_config.h>
#include <ut_trace.h>
#include <sys/stat.h>
#include <sys/types.h>
}
C++ 标准没有指定编译器应如何命名其目标文件中的符号(例如,Foo::bar()
最终可能会成为__clsFoo_fncBar
或一些 gobbledygook)。C 标准确实如此,而且它几乎总是与 C++ 编译器的做法不同(C 不必处理类、命名空间、重载等)。
因此,当您链接一个由 C 编译器输出的目标文件时,您必须告诉您的 C++ 编译器查找名称与 C 标准相对应的符号。您实际上是将其置于“C 模式”。这就是"C"
部分extern "C"
所做的。
(或者,您可能还声明了可由外部 C 对象文件使用的函数或变量。在这种情况下,这意味着以 C 方式导出这些符号。)
如果您的项目有 C 和 C++ 源文件,并且您需要整体构建(C 文件调用 C++ 文件中的某些函数),那么我们需要通过在 C++ 文件中声明如下来保护 C 文件函数调用和符号
extern "C" { / c 文件中使用的符号/ uint8 GetCurrentthreadState(HANDLE ThreadId)
}
然后 C++ 编译器为上述声明的函数和符号生成与 C 编译器相同的编译输出。因此在链接时,编译器可以轻松链接 C 和 C++ 定义的符号而不会出现任何链接错误。
所以我的意见不需要对编译进行#ifdef __cplusplus检查。因为我们需要保护 c++ 文件中的符号,对吗?C++ 文件也只能由 C++ 编译器编译,对吗?
/伦吉特克
它不起作用,您需要添加 cplusplus 预处理器...
#ifdef __cplusplus
extern "C" {
#endif
// your code
#ifdef __cplusplus
}
#endif
编辑:
在 C++ 中,名称将像在 C 中一样处理,这意味着不会有 mangle 名称。它允许区分具有不同参数类型/编号或库中不同命名空间的两个 C++ 不同函数(用于库目的 libname.so、libname.a)。如果名称损坏,C 程序将无法识别它
eg:
int myfction()
void myfunction(int)
void myfunction(int, char)
C library: myfction
C++ library: int_myction (it depend on your compiler)
C++ library: int_myction_int (it depend on your compiler)
C++ library: int_myction_int_char (it depend on your compiler)
// ... which is not allowed in C program
每个 C++ 编译器都需要支持外部“C”链接。这种块中的代码可以是用 C 语言编写的用于特定功能的遗留代码,这是当前程序所必需的。
这是如何实现的主要取决于编译器,但是我听说许多编译器禁用名称修饰并更改调用约定。