繁体   English   中英

extern“C”如何在C文件中允许C ++代码?

[英]how does extern “C” allow C++ code in a C file?

为了在C文件中使用C ++代码,我读到我们可以做extern "C" { (where the c++ code goes here)} ,但是当我尝试使用cout打印出来时,我不断收到错误,因为它无法识别图书馆。 我想我对extern“C”如何允许你在C中使用C ++代码感到困惑。

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

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

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

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

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

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

这允许您拥有一个具有混合C和C ++源的项目,并且C源可以调用已定义为extern "C"的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");
}

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 ++。

导出的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库链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM