



全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
extern C的作用extern C的作用(一) 前些天,编程序是用到了很久以前写的C程序,想把里面的函数利用起来,连接发现出现了找不到具体函数的错误: 以下是假设旧的C程序库 C的头文件 /*-c.h-*/ #ifndef _C_H_ #define _C_H_ extern int add(int x, int y); #endif C的源文件 /*-c.c-*/ int add(int x, int y) return x+y; C+的调用 /*-cpp.cpp-*/ #include c.h void main() add(1, 0); 这样编译会产生错误cpp.obj : error LNK2001: unresolved external symbol int _cdecl add(int,int) (?addYAHHHZ),原因是找不到add的目标模块 这才令我想起C+重载的函数命名方式和C函数的命名方式,让我们回顾一下:C中函数编译后命名会在函数名前加以_,比如add函数编译成obj文件时的实际命名为_add,而c+命名则不同,为了实现函数重载同样的函数名add因参数的不同会被编译成不同的名字 例如 int add(int , int)=addYAHHHZ, float add(float , float )=addYAMMMZ, 以上是VC6的命名方式,不同的编译器会不同,总之不同的参数同样的函数名将编译成不同目标名,以便于函数重载是调用具体的函数. 编译cpp.cpp中编译器在cpp文件中发现add(1, 0);的调用而函数声明为extern int add(int x, int y);编译器就决定去找addYAHHHZ,可惜他找不到,因为C的源文件把extern int add(int x, int y);编译成_add了; 为了解决这个问题C+采用了extern C,这就是我们的主题,想要利用以前的C程序库,那么你就要学会它,我们可以看以下标准头文件你会发现,很多头文件都有以下的结构 #ifndef _H #define _H #ifdef _cplusplus extern C #endif extern int f1(int, int); extern int f2(int, int); extern int f3(int, int); #ifdef _cplusplus #endif #endif /*_H*/ 如果我们仿制该头文件可以得到 #ifndef _C_H_ #define _C_H_ #ifdef _cplusplus extern C #endif extern int add(int, int); #ifdef _cplusplus #endif #endif /* _C_H_ */ 这样编译 /*-c.c-*/ int add(int x, int y) return x+y; 这时源文件为*.c,_cplusplus没有被定义,extern C 这时没有生效对于C他看到只是extern int add(int, int); add函数编译成_add(int, int); 而编译c+源文件 /*-cpp.cpp-*/ #include c.h void main() add(1, 0); 这时源文件为*.cpp,_cplusplus被定义,对于C+他看到的是extern C extern int add(int, int);编译器就会知道 add(1, 0);调用的C风格的函数,就会知道去c.obj中找_add(int, int)而不是addYAHHHZ; 这也就为什么DLL中常看见extern C ,windows是采用C语言编制他首先要考虑到C可以正确调用这些DLL,而用户可能会使用C+而extern C 就会发生作用 extern C的作用(二) 一、修饰名(Decorated Name) C/C+程序中的函数在内部是通过修饰名来标识的.修饰名是在函数定义或原型编译阶段由编译器创建字符串.当你在LINK等工具中要指定一个函数名时,会用到修饰名. 1、使用修饰名: 大多数情况下,你不必知道函数的修饰名是什么.连接器等工具通常都能处理函数未修饰的名字.然而,在有些情况下,你可能需要指定函数的修饰名.对于C+重载函数和特定的成员函数(如:构造函数和析构函数),你必须指定这些函数的修饰名,以便连接器等工具能够匹配名字.同时,你也必须在那些引用c或c+函数名的汇编源文件中使用修饰名. 2、查看修饰名: 如果你编译了一个源文件,该源文件中包含了函数定义或原型,你可以获得函数的修饰名形式. (1)用编译器列表(compiler listing)来查看: (i)通过将列表文件类型编译器选项(/FAc|s) 设置为下面中的一种,来产生列表文件:Assembly with Machine Code (/FAc); Assembly with Source Code (/FAs); Assembly, Machine Code, and Source (/FAcs). (ii)在产生的列表文件中,找到包含未经修饰的函数定义的行. (iii)查找前面一行.PROC NEAR 命令标签前就是函数名经过修饰后的形式. (2)使用DUMPBIN工具来查看: 在.OBJ或.LIB上运行 DUMPBIN,使用/SYMBOLS选项.在输出中查找未经修饰的函数定义.后面跟着的就是经过修饰的函数名,用圆括号括起来的. 二、替代连接说明: 如果在c+中编写一个程序需要用到c的库,那该如何?如果这样声明一个c函数: void f(int a,char b); c+编译器就会将这个名字变成相应的修饰名,比如:?fYAXHDZ. 然而,c编译器编译的库的内部函数名(连接器使用)是完全不同的.这样,当c+连接器连接c的函数库时,将会产生内部使用函数不匹配. 故,c+中提供了一个替代连接说明(alternate linkage specification),它是通
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公司毛衣直播策划方案
- 公司行政服务活动方案
- 公司组织跑步小活动方案
- 公司校招策划方案
- 公司春节后开业活动方案
- 公司新春慰问福利活动方案
- 公司瑜伽学习活动方案
- 公司组织制作香熏活动方案
- 公司氛围策划方案
- 公司聚会桌面活动方案
- 中考物理考前指导最后一课
- 盐酸罂粟碱在疼痛治疗中的应用
- 创设生活化教学与情境模拟
- 中国近代史纲要-期末考试复习重点
- 企业法务概论智慧树知到期末考试答案2024年
- (高清版)DZT 0331-2020 地热资源评价方法及估算规程
- GB/T 7939.1-2024液压传动连接试验方法第1部分:管接头
- 低压配电系统维护保养及操作规程
- 肝癌科普讲座课件
- 学龄儿童多动症ADHD诊治指南课件
- 石膏固定术课件
评论
0/150
提交评论