何时使用外部"C"?
When to use extern "C"?
我知道如何使用extern "C"
,但是在什么条件下你必须使用它?
例如:
extern "C"
告诉c++编译器不要对括号内的代码。这允许你调用C函数在c++中。
#include <string.h>
int main()
{
char s[] = "Hello";
char d[6];
strcpy_s(d, s);
}
而这在vc++上编译得很好。但有时也写成:
extern "C" {
#include <string.h>
}
我不明白这有什么意义。你能给出一个需要extern "C"
的真实例子吗? 您使用extern "C"
来防止头文件和c++对象文件中的名称混淆对于已经编译过的库或对象
例如,假设你有一个widget
库,它是用C编译器编译的,所以它发布的接口是无篡改的。
如果您将头文件原样包含到您的代码中,它将假定名称是混乱的,并且这些混乱的版本是您将告诉链接器查找的。
然而,由于您将要求function@intarray_float_charptr
之类的东西,而widget
库将只发布function
,因此您将遇到问题。
但是,如果你用:
extern "C" {
#include "widget.h"
}
你的编译器将知道它应该尝试使用function
,未修改的版本。
这就是为什么,在C或c++程序中包含的C内容的头文件中,您会看到这样的内容:
#ifdef __cplusplus
extern "C" {
#endif
// Everything here works for both C and C++ compilers.
#ifdef __cplusplus
}
#endif
如果你使用C编译器来包含这个,#ifdef
行会导致extern "C"
的东西消失。对于c++编译器(其中定义了__cplusplus
),所有内容都是非mangmanged的。
当您从库导出函数时,extern "C"
的一个非常常见的用途。如果你不禁用c++的名称混淆,那么你的库的客户端很难命名你的函数。同样地,在另一个方向上,当您导入使用C链接导出的函数时。
这是一个具体的例子,事情打破了,需要extern "C"
得到修复。
module.h
:
int f(int arg);
module.c
:
int f(int arg) {
return arg + 1;
}
main.cpp
:
#include "module.h"
int main() {
f(42);
}
由于我混合了C和c++,这不会链接(在两个目标文件中,只有一个会知道f
在其c++名称下)。
module.h
:
#ifdef __cplusplus
extern "C" {
#endif
int f(int arg);
#ifdef __cplusplus
}
#endif
当您链接用C编写的库时,extern
告诉编译器不要修饰名称,以便链接器可以找到这些函数。在c++中,函数名等包含了链接器的信息,例如参数类型和大小。
如果你正在生成一个二进制库a,它公开了一个你想从二进制b中调用的函数
假设A是A.dll, B是B.exe,你在Windows系统上。
c++没有描述二进制布局,使得B知道如何调用a。通常这个问题可以通过使用相同的编译器来生成a和B来解决。如果你想要一个更通用的解决方案,你可以使用extern关键字。这将以C的方式公开函数。C确实描述了一种二进制格式,这样来自不同编译器的不同二进制文件就可以相互通信。
看:http://en.wikipedia.org/wiki/Application_binary_interfacehttp://en.wikipedia.org/wiki/Name_mangling Name_mangling_in_C.2B.2B
如果,在你的c++代码中,你#include
一个外部库的头(用C编码),如果函数中没有声明extern "C"
,它们就不能工作(你会在链接时得到未定义的引用)。
但是现在,编写C库并为您提供头文件的人往往知道这一点,并且经常将extern "C"
放在他们的头文件中(适当地使用#ifdef __cplusplus
保护)
也许更好的理解方法是使用(假设您有Linux系统)nm
实用程序来显示库或可执行文件中使用的(未修改的)名称。
- 使外部项目可用于find_package CMake
- 何时使函数成为类成员函数C++?
- C++使用其他命名空间中的符号,而不使它们可从外部访问
- 将外部C++库与 CMake 一起使用时出错
- 何时必须使操作员<<过载?
- 如何使结构内部的可变参数模板可以在外部访问?
- LLVM - 如何使嵌套函数看到外部函数的变量
- 在Windows上,何时有必要将附加到目录路径上,以使_stat成功
- 使用线程控制访问外部API的对象
- 当外部变量在其他文件中声明不同时,如何使G 产生警告
- 使外部应用在OS X应用程序的顶部浮动
- 当与可能导致缓冲区溢出的功能一起使用时,外部变量是否比其他变量更大
- 外部"C" ---何时*确切*使用?
- 何时使用外部链接初始化全局常量,避免静态初始化顺序惨败
- 如果引发异常,则使外部C++函数返回一条消息
- 是否可以通过外部链接使功能过载
- 无法使Flandmarks工作,C++,错误LNK2019,未解决的外部符号
- 当使用时从外部隐藏类仅用于C++中的API内部
- Apple C++ LLVM Compiler 4.x & UNICODE:何时需要?UNICODE 是默认编译器字符集吗?使代码同时编译 ANSI 和 UNICODE 版本
- 何时使用外部"C"?