extern "C"

C/C++采用的是分别编译模型, 源代码只要声明函数, 就可调用。

编译时,在函数调用处生成一个符号引用。

链接时,将函数调用处的符号引用,替换成地址(甚至仍有可能继续保留符号, 载入时再计算地址)。

所以, 以下两者必须完全比配, 否则链接时会出错。

1. 函数调用处引用的符号名

2. 函数定义处公开的符号名

如何使得两者匹配?

无论是在调用处还是在定义处, 无论是C还是C++(注1), 编译器都会对函数名进行mangling, 产生一个符号名。

而 extern "C" 就是通知C++编译器(注2), 将某函数按照C的规则进行mangling, 产生符号名。

如果是在声明处使用 extern "C", 函数调用处引用的符号名将按C的mangling规则产生。

如果是在定义处使用 extern "C", 翻译单元里公开的符号名将按C的mangling规则产生。

同时, C编译器将 extern "C" 视为错误—— 所以需要类似的代码

?
1
2
3
4
5
6
7
8
9
#ifdef __cplusplus
extern  "C"  {
#endif 
 
/*...*/ 
 
#ifdef __cplusplus
}
#endif

extern "C" 通常使用的地方。

1. 当一个函数已经由C编译器实现

在一个C++翻译单元中, 必须使用 extern "C" 声明改函数。

这样, 该函数调用产生的符号名引用和已经由C编译器实现的函数的符号名才能匹配。

2. 用C++编译器实现C和C++都可调用的函数。

自己声明extern “C”。 在C++翻译单元中, 该函数名按C规则修饰之后, 得到符号名, 并公开。

C++的调用者依然需要使用 extern "C" 来声明。

C的调用者直接声明。

目的也是为了使得引用与实现的符号名匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值