简体   繁体   English

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

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

In order to use C++ code in a C file, I read that we can just do extern "C" { (where the c++ code goes here)} , but when I try printing something out using cout, I keep getting an error because it does not recognize the library . 为了在C文件中使用C ++代码,我读到我们可以做extern "C" { (where the c++ code goes here)} ,但是当我尝试使用cout打印出来时,我不断收到错误,因为它无法识别图书馆。 I think I am just confused on how extern "C" allows you to use C++ code in C. 我想我对extern“C”如何允许你在C中使用C ++代码感到困惑。

The opposite is true. 反之亦然。 You can use extern C to add code you want to compile as C code using a C++ compiler. 您可以使用extern C使用C ++编译器添加要编译为C代码的代码。

Unless I'm missing something you can't compile C++ code with a C compiler. 除非我遗漏了一些东西,否则你无法使用C编译器编译C ++代码。

The extern "C" construct is a C++-specific syntax, no C compiler will understand it. extern "C"构造是一种特定于C ++的语法,没有C编译器会理解它。

That's why you will almost always see it paired with some conditional compilation like 这就是为什么你几乎总会看到它与一些条件编译配对

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

What extern "C" does is simply to inhibit name mangling meaning that symbols defined in a C++ source file can be used in a C program. extern "C" 作用仅仅是禁止名称修改,这意味着C ++源文件中定义的符号可以在C程序中使用。

This allows you to have a project with mixed C and C++ sources, and the C source can call the C++ functions that have been defined as extern "C" . 这允许您拥有一个具有混合C和C ++源的项目,并且C源可以调用已定义为extern "C"的C ++函数。

Very simple, and stupid, example just to show the point: 非常简单,愚蠢的例子只是为了说明这一点:

Lets say we have a C source file, compiled with a C compiler: 假设我们有一个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;
}

Then we have a C++ source file for the foo function: 然后我们有一个foo函数的C ++源文件:

#include <iostream>

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

The C source file is compiled with a C compiler, and the C++ source file is compiled with a C++ compiler. C源文件使用C编译器编译,C ++源文件使用C ++编译器编译。 Then the two object files are linked together to form the executable program. 然后将两个目标文件链接在一起以形成可执行程序。 Because foo was defined as extern "C" it's symbol name in the object file is not mangled, and the linker can resolve the reference from the object file created by the C compiler. 因为foo被定义为extern "C" ,所以目标文件中的符号名称不会被破坏,链接器可以解析C编译器创建的目标文件中的引用。

It works in the other direction as well. 它也适用于另一个方向。 Because symbols in C are not mangled the C++ compiler needs to know that, and that is done by declaring the C symbols extern "C" , usually in a header file using the conditional compilation as shown above. 因为C中的符号没有被破坏,所以C ++编译器需要知道这一点,并且通过使用如上所示的条件编译通常在头文件中声明C符号extern "C"来完成。 If extern "C" was not used, the C++ compiler would think that the symbols were C++ symbols, and mangle the names leading to linker problems when the linker can't find the mangled symbols. 如果未使用extern "C" ,则C ++编译器会认为符号是C ++符号,并且当链接器无法找到损坏的符号时,会破坏导致链接器问题的名称。

Equally stupid example: First a C++ source file 同样愚蠢的例子:首先是一个C ++源文件

#include <iostream>

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

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

Then the C source file 然后是C源文件

#include <stdio.h>

void bar(void)
{
    printf("Inside bar\n");
}

extern "C" is a way of putting C code in C++ code. extern "C"是一种将C代码放入C ++代码的方法。 More specifically it tells the compiler to disable certain things like function overloading so that it can also turn off the name mangling. 更具体地说,它告诉编译器禁用某些功能,例如函数重载,这样它也可以关闭名称修改。 In C++ a simple function like: 在C ++中,一个简单的函数如:

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

Will actually get some funky name in the library to denote the parameters so that if you define another function like: 实际上会在库中获得一些时髦的名称来表示参数,这样如果你定义另一个函数,如:

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

That it knows which one to call. 它知道要拨打哪一个。 You don't want that if you're trying to use a C library and that's what extern "C" is for. 如果您正在尝试使用C库,那么您不希望这样,那就是extern "C"的用途。 All of this being said, extern "C" does not allow C++ in a C program. 所有这些都说, extern "C"不允许在C程序中使用C ++。

Exported C++ symbols, as generated my the compiler, are mangled to include additional type information about the symbol to the linker. 导出的C ++符号(由编译器生成) 被修改为包含有关符号的其他类型信息到链接器。

So the following overloaded functions would be distinguishable by the linker in C++, but not C: 因此,C ++中的链接器可以区分以下重载函数,但不能区分C:

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

The extern "C" { ... } syntax allows symbols (or references to C symbols) to be defined in C++ code without using the mangling rules. extern "C" { ... }语法允许在C ++代码中定义符号(或对C符号的引用),而不使用mangling规则。 This allows such C++ code to be linked with C libraries. 这允许这样的C ++代码与C库链接。

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

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