1

这在 C 或 C++ 中如何工作?

extern "C" {
#include <unistd.h>
#include <fd_config.h>
#include <ut_trace.h>
#include <sys/stat.h>
#include <sys/types.h>
}
4

4 回答 4

5

C++ 标准没有指定编译器应如何命名其目标文件中的符号(例如,Foo::bar()最终可能会成为__clsFoo_fncBar或一些 gobbledygook)。C 标准确实如此,而且它几乎总是与 C++ 编译器的做法不同(C 不必处理类、命名空间、重载等)。

因此,当您链接一个由 C 编译器输出的目标文件时,您必须告诉您的 C++ 编译器查找名称与 C 标准相对应的符号。您实际上是将其置于“C 模式”。这就是"C"部分extern "C"所做的。

(或者,您可能还声明了可由外部 C 对象文件使用的函数或变量。在这种情况下,这意味着以 C 方式导出这些符号。)

于 2010-02-15T07:12:34.817 回答
2

如果您的项目有 C 和 C++ 源文件,并且您需要整体构建(C 文件调用 C++ 文件中的某些函数),那么我们需要通过在 C++ 文件中声明如下来保护 C 文件函数调用和符号

extern "C" { / c 文件中使用的符号/ uint8 GetCurrentthreadState(HANDLE ThreadId)

}

然后 C++ 编译器为上述声明的函数和符号生成与 C 编译器相同的编译输出。因此在链接时,编译器可以轻松链接 C 和 C++ 定义的符号而不会出现任何链接错误。

所以我的意见不需要对编译进行#ifdef __cplusplus检查。因为我们需要保护 c++ 文件中的符号,对吗?C++ 文件也只能由 C++ 编译器编译,对吗?

/伦吉特克

于 2010-02-15T08:54:19.120 回答
1

它不起作用,您需要添加 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
于 2010-02-15T07:04:37.383 回答
0

每个 C++ 编译器都需要支持外部“C”链接。这种块中的代码可以是用 C 语言编写的用于特定功能的遗留代码,这是当前程序所必需的。

这是如何实现的主要取决于编译器,但是我听说许多编译器禁用名称修饰并更改调用约定。

于 2010-02-15T08:35:37.557 回答