8

为了在 C 文件中使用 C++ 代码,我读到我们可以这样做extern "C" { (where the c++ code goes here)},但是当我尝试使用 cout 打印一些东西时,我不断收到错误,因为它无法识别库。我想我只是对 extern "C" 如何允许您在 C 中使用 C++ 代码感到困惑。

4

4 回答 4

12

反之亦然。您可以使用 extern C 添加要使用 C++ 编译器编译为 C 代码的代码。

除非我遗漏了一些东西,否则您无法使用 C 编译器编译 C++ 代码。

于 2016-04-22T04:59:17.663 回答
10

extern "C"构造是特定于 C++ 的语法,没有 C 编译器能够理解它。

这就是为什么您几乎总是会看到它与一些条件编译配对,例如

#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif

extern "C" 所做的只是禁止名称修改,这意味着在 C++ 源文件中定义的符号可以在 C 程序中使用。

这允许您拥有一个混合了 C 和 C++ 源代码的项目,并且 C 源代码可以调用已定义为extern "C".

非常简单且愚蠢的示例只是为了说明这一点:

假设我们有一个用 C 编译器编译的 C 源文件:

#include <stdio.h>

void foo(void);  // Declare function prototype, so it can be called

int main(void)
{
    printf("Calling foo...\n");
    foo();
    printf("Done\n");

    return 0;
}

然后我们有一个foo函数的 C++ 源文件:

#include <iostream>

extern "C" void foo()
{
    std::cout << "Hello from foo\n";
}

C源文件用C编译器编译,C++源文件用C++编译器编译。然后将两个目标文件链接在一起形成可执行程序。因为foo被定义为extern "C"它在目标文件中的符号名称没有被破坏,并且链接器可以解析来自 C 编译器创建的目标文件的引用。

它也适用于另一个方向。因为 C 中的符号没有被破坏,所以 C++ 编译器需要知道这一点,这是通过声明 C 符号来完成的extern "C",通常在头文件中使用如上所示的条件编译。如果extern "C"不使用,C++ 编译器会认为这些符号是 C++ 符号,并且当链接器找不到被损坏的符号时,会损坏导致链接器问题的名称。

同样愚蠢的例子:首先是一个 C++ 源文件

#include <iostream>

extern "C" void bar();  // Declare function prototype as an unmangled symbol

int main()
{
    std::cout << "Calling bar...\n";
    bar();
}

然后是C源文件

#include <stdio.h>

void bar(void)
{
    printf("Inside bar\n");
}
于 2016-04-22T05:05:10.173 回答
2

extern "C"是一种将 C 代码放入 C++ 代码中的方法。更具体地说,它告诉编译器禁用某些功能,例如函数重载,以便它也可以关闭名称修饰。在 C++ 中,一个简单的函数如下:

int add(int a, int b) {
    return a+b;
}

实际上会在库中获得一些时髦的名称来表示参数,这样如果您定义另一个函数,例如:

double add(double a, double b) {
    return a+b;
}

它知道该调用哪一个。如果您尝试使用 C 库,那么您不希望这样,这就是extern "C"目的。综上所述,extern "C"C 程序中不允许使用 C++。

于 2016-04-22T05:07:06.673 回答
1

由编译器生成的导出的 C++ 符号被修改以包含有关链接器的符号的附加类型信息。

因此,C++ 中的链接器可以区分以下重载函数,但 C 不能区分:

  • int fn();
  • int fn(int);
  • int fn(char*);
  • int fn(char*) const;
  • int fn(const char*);

extern "C" {...语法允许在 C++ 代码中定义符号(或对 C 符号的}引用)而不使用mangling规则。这允许将此类 C++ 代码与 C 库链接。

于 2016-04-22T05:18:13.487 回答