之前帮老板编译一个库的代码,遇到了一些问题,后来发现问题出现在extern "C"语法上。

  1. C/C++语法extern 关键字

  extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。”----百度百科。值得注意的是extern int a,仅是一个声明, 可以在程序中出现多次,并没有分配存储空间,然而变量a作为全局变量,变量a的定义仅能出现一次。

// A.cpp
int i;
int main()
{
return ;
} // B.cpp
int i = 100;

  编译A.cpp文件,B.cpp文件不会提示有错误,在编译阶段,各个文件中定义的全局变量相互是不透明的,编译A时觉察不到B中也定义了i,同样,编译B时觉察不到A中也定义了i。但是在链接阶段,A与B文件融合在一起,全部变量都存在程序的静态存储区域,因此会有如下报错:

  但是,我们直接使用B.cpp中定义的变量,编译器并没有先见之明,在编译阶段无法知道变量定义在文件中,如下代码:

// A.cpp
//int i;
#include <iostream> using namespace std; int main()
{
cout<<i;
return ;
} // B.cpp
int i=;

将会提示:“错误 1 error C2065: “i”: 未声明的标识符 d:\程序\test\extern\a.cpp 9 1 extern”

  为此,关键字"extern",便发挥了它的作用,在A.cpp文件中添加声明:extern int i;

// A.cpp
//int i;
extern int i;
#include <iostream> using namespace std; int main()
{
cout<<i;
return ;
} // B.cpp
int i=;

程序正常运行输出:100;

  2. C++ extern "C" 语法缘由

  C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:void foo( int x, int y );
该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。
  在被编译的c++程序中,如果调用了其他的库的函数,则这个函数名也是照加了附加信息的函数名来调的,这样,如果这个库是c方式编译的,那么在库中的函数名是不带附加信息的,这样的调用链接就会失败,因为函数名不对应导致找不到,出现连接错误
  为了解决这个问题,C++引入extern “C”。extern “C”是告诉编译器:这是一个用C写成的库文件,请用C的方式来链接它们。

  3. 一般用法

  经常在项目文件看到的extern “C”的用法:

 #ifdef __cplusplus
extern "C" {
#endif // 代码 #ifdef __cplusplus
}
#endif

  代码部分可以是:调用库函数头文件(ie. #include <c.h>、调用函数声明(ie. extern int add())、一段函数代码实现。需要注意宏__cplusplus,标志着编译器将会把代码按C还是C++语法来解释,目的是这个文件既可以被C调用也可以被C++调用。因为C并没有extern “C”语法,因此如果不加宏编译,编译器会报错的。

最新文章

  1. appium for hybrid app 处理webview
  2. Linux内核分析:dup、dup2的实现
  3. route命令
  4. Socket编程基础——无连接UDP
  5. PYTHON入门知识
  6. 如何在redhat下安装WineQQ
  7. [转]将Word转(保存)为带书签的PDF
  8. 【转】前端图片该保存为什么格式?png or jpg?
  9. SQL Server中时间段查询和数据类型转换
  10. 一个获取Android手机root权限的程序
  11. window对象的属性
  12. 03_Android项目中读写文本文件的代码
  13. W3bsafe]SQLmap过狗命令的利用+教程
  14. lemon special judge模板
  15. 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)
  16. WebRTC网关服务器单端口方案实现
  17. css关于定位那些事情
  18. jquery 实现iframe 自适应高度
  19. 52 53django
  20. python并发编程之多进程理论部分

热门文章

  1. 键值对集合 dict(字典)
  2. DataUml Design 教程4-代码生成
  3. Java基础07 包(转载)
  4. Linux 常用文件管理命令
  5. [ JS 进阶 ] 基本类型 引用类型 简单赋值 对象引用 (转)
  6. PostgreSQL tips
  7. C++资源文件初使用[C++菜鸟]
  8. ASSERT(m_hWnd == hWndOrig) - 解决之
  9. MySQL没有远程连接权限设置
  10. 《从零开始学Swift》学习笔记(Day 3)——Swift 2.0之后增加的关键字