2022年externC的作 .pdf

上传人:Che****ry 文档编号:34261889 上传时间:2022-08-15 格式:PDF 页数:4 大小:39.52KB
返回 下载 相关 举报
2022年externC的作 .pdf_第1页
第1页 / 共4页
2022年externC的作 .pdf_第2页
第2页 / 共4页
点击查看更多>>
资源描述

《2022年externC的作 .pdf》由会员分享,可在线阅读,更多相关《2022年externC的作 .pdf(4页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、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 : e

2、rror LNK2001: unresolved external symbol int _cdecl add(int,int) (?addY AHHHZ), 原因是找不到add 的目标模块这才令我想起C+重载的函数命名方式和C 函数的命名方式,让我们回顾一下:C 中函数编译后命名会在函数名前加以_, 比如 add 函数编译成obj 文件时的实际命名为_add,而 c+命名则不同 ,为了实现函数重载同样的函数名add 因参数的不同会被编译成不同的名字例如int add(int , int)=addY AHHHZ, float add(float , float )=addY AMMMZ, 名师

3、资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 4 页 - - - - - - - - - 以上是VC6 的命名方式 ,不同的编译器会不同,总之不同的参数同样的函数名将编译成不同目标名 ,以便于函数重载是调用具体的函数. 编译 cpp.cpp 中编译器在 cpp 文件中发现add(1, 0);的调用而函数声明为extern int add(int x, int y); 编译器就决定去找addYAHHHZ, 可惜他找不到,因为 C 的源文件把extern int add(int

4、 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

5、 _C_H_ #define _C_H_ #ifdef _cplusplus extern C #endif extern int add(int, int); #ifdef _cplusplus #endif #endif /* _C_H_ */ 这样编译名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 4 页 - - - - - - - - - /*-c.c-*/ int add(int x, int y) return x+y; 这时源文件为*.c,_cplusplu

6、s没有被定义,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 中

7、常看见extern C ,windows是采用 C 语言编制他首先要考虑到C 可以正确调用这些DLL, 而用户可能会使用C+而 extern C 就会发生作用extern C的作用 (二) 一、修饰名 (Decorated Name) C/C+程序中的函数在内部是通过修饰名来标识的.修饰名是在函数定义或原型编译阶段由编译器创建字符串.当你在 LINK 等工具中要指定一个函数名时,会用到修饰名. 1、使用修饰名 : 大多数情况下 ,你不必知道函数的修饰名是什么.连接器等工具通常都能处理函数未修饰的名字.然而 ,在有些情况下,你可能需要指定函数的修饰名.对于C+重载函数和特定的成员函数(如:构造函

8、数和析构函数),你必须指定这些函数的修饰名,以便连接器等工具能够匹配名字.同时 ,你也必须在那些引用c 或 c+函数名的汇编源文件中使用修饰名. 2、查看修饰名 : 如果你编译了一个源文件,该源文件中包含了函数定义或原型,你可以获得函数的修饰名形式. (1)用编译器列表 (compiler listing) 来查看 : (i) 通 过 将列 表文 件 类型 编译 器 选项 (/FAc|s) 设 置为 下 面中 的一 种,来产 生列 表 文名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第

9、 3 页,共 4 页 - - - - - - - - - 件: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选项 .在输出中查找未经修饰的函数定义.后面跟着

10、的就是经过修饰的函数名,用圆括号括起来的. 二、替代连接说明: 如果在 c+中编写一个程序需要用到c 的库 ,那该如何 ?如果这样声明一个c 函数 : void f(int a,char b); c+编译器就会将这个名字变成相应的修饰名,比如 :?fYAXHDZ. 然而 ,c 编译器编译的库的内部函数名(连接器使用 )是完全不同的 .这样 ,当 c+连接器连接c 的函数库时 ,将会产生内部使用函数不匹配. 故,c+ 中提供了一个替代连接说明(alternate linkage specification), 它是通过重载extern关键字来实现的 . extern 后跟一个字符串来指定想声明的函数的连接类型,后面是函数声明,比如 : extern C void f(int a,char b); 这样 ,就是告诉编译器是c 连接,这样就不会转换函数名了.此例中 ,编译后的内部函数名是_f. 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 4 页 - - - - - - - - -

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁