extern "C"
2019-08-16 07:53:23来源:博客园 阅读 ()
extern "C"
我们在使用别人提供的 API 时,经常会看到头文件中有 extern "C" 的字样,有的头文件中写的是
1 #ifdef __cplusplus 2 extern "C" 3 { 4 #endif 5 ......./*函数声明*/ 6 7 #ifdef __cplusplus 8 } 9 #endif
只有在C++编译中,extern "C" 才会生效。
它的作用是避免 C++ 编译器的 name mangling. 有人说C++编译器在代码后边为我们做了一些意想不到的事,这太可怕了。C++ 大师Lippman 调侃说C++编译器具有唯物主义色彩。
那么C++编译器会自动为我们的C++代码做什么事呢?其中比较常见的有自动合成构造函数,析构函数等,还有name mangling。
我们知道C是没有函数重载的,我们不能在C语言中定义多个参数,返回值不同的同名函数,C++是允许的。第一款C++编译器是用C语言实现的(cfront),它将C++代码转换为C语言。那么cfront怎么支持C++的函数重载机制的呢?cfront 对C++函数做了处理,比如以下代码
1 void Fun(); 2 void Fun(char, char); 3 void Fun(int);
在经过C++编译器处理后的结果可能是(我会在后续的博文中找到 VC++和G++怎么处理的样例)
1 void Fun_v(); 2 void Fun_c_c(char, char); 3 void Fun_i(int);
这样就能够实现同名函数的重载了。
当我们使用
Fun('a', 'b');
调用函数的时候,可能转换为
1 Fun_c_c('a', 'b');
在第一篇hello world 中,简单说了编译的几个步骤,上边这一步是在compile 的时候做的。(compile 时需要找到这个函数的声明)
最后在link 的阶段,是需要找到该函数的定义的。由于compile 时处理了函数名称,函数定义中的名称也随之更改了。在link的结果中是没有 Fun 这个函数的定义的。
如果我们的代码是生产动态链接库(dll 或者 so 文件),那么在 nm 的时候,看到的是处理过的函数名。
回到我们的主题:
extern "C" C++编译器设置了一个开关,让函数的作者来决定是不是需要做名称处理。如果作者希望C++和C的使用者都可以调用它,一般会加上 extern "C" 的关键字来压制编译器的命名处理。
如果我们拿到一套别人提供的API,这套 API 是C编译器编译的,我们使用C++编译器编译调用API的代码时,经常会出现link时说找不到函数定义。nm 查看动态库的时候发现是有这个函数的,这种情况有两种处理方式:
1. 改用C编译器
2. 在头文件中加上 extern "C" 来抑制C++编译器的命名处理。
如果没有用到C++中的模板,STL,OO等功能,换C语言编译器就行,如果用到了这些,那就将头文件改了吧。
原文链接:https://www.cnblogs.com/kylinhu/p/11231166.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:2019年7月训练(壹)
下一篇:长乐培训Day3
- Unsolved --> Solved OJ思路题解 2020-05-30
- Building & Debugging chromium on CLion for Linu 2020-05-19
- 洛谷P1164->小A点菜 2020-05-18
- 表达式·表达式树·表达式求值 2020-04-29
- STL之<string> 2020-04-05
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash