外部"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("Donen");
return 0;
}
然后我们有一个foo
函数的C++源文件:
#include <iostream>
extern "C" void foo()
{
std::cout << "Hello from foon";
}
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 barn");
}
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 库链接。
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值