有关动态库总结!(19)
来源:互联网 发布:黑客攻击软件 编辑:程序博客网 时间:2024/06/01 08:06
(19)动态库中的_declspec(import)和_declspec(export):
在导出的时候,添加_declspec(export),告诉编译器此函数需要导出:
_declspec(export) add(int,int);
如果添加extern “C”则告诉编译器,用C语言的不改名方式去导出add(int,int)函数
extern "C" _declspec(export) add(int,int);
对于_declspec(export)这个关键词而言,如果编译器看到它,会在生成的.obj文件中加入一些额外的信息。当链接器在链接Dll所有的.obj时,会解析这些信息。即当链接生成dll文件时,链接器会检测这些额外添加的信息,并且根据这些信息生成一个.lib文件。这个lib文件会列出该dll导出的符号。
除此之外,链接器还会在Dll文件中嵌入一个导出符号表,这个导出段(按字符顺序排列的)列出了导出的变量,函数和类的符号名。并且链接器还会保存相对虚拟地址,表示每个符号可以在DLL模块中的何处找到。(所以在代码中使用LoadLibrary(),GetProcAddress()等函数显式的调用dll)
另外,在使用extern "C" 时,如果使用VC++编译器,并且函数调用方式为_stdcall时,编译器还是会改编其到处的函数名,所以这时只能使用.def文件定义到处符号。具体使用如下:
EXPORTS
add
当编译器解析这个def文件时,会发现add改编后的名字和add都被导出。由于这两个名字是匹配的(不考虑改编),因此,链接器会使用.def中定义的名称导出。当然如果不想创建一个.def文件,可以使用
#pragma comment(linker,"/export:add=_MyFunc@8");
其中的_MyFunc@8是VC++编译器对上诉_stdcall调用方式改编的名字。这个代码的作用是,告诉编译器产生一个连接器指示符,该指示符告诉链接器要导出一个名为add的函数,该函数的入口点与_MyFunc@8相同。需要注意的是:这个仅仅是能让我们避免使用.def文件而已,并没有什么特别之处。
在导入的时候,添加_declspec(import),告诉编译器此函数需要导入:
_declspec(import) add(int,int);
同上,添加extern "C"作用类似。
当然,我们也可以不使用_declspec(import),直接用extern关键词。但是,如果编译器能够提前知道我们要引用的符号是从一个DLL的.lib文件中导入的,那么它将能够产生略微高效的代码。所以推荐大家使用_declspec(import)。
另外需要注意:当编译器看到_declspec(import)时,会知道其因该从某个dll模块导入该符号,但是编译器不知道具体的dll是哪一个,编译器只想确认我们以正确方式来访问这些符号而已。关于具体中从哪个dll导入,实在链接过程中,链接器需要确认代码中引用的符号是来自哪个dll的。因此我们需要将dll的.lib文件传给链接器。
但是.lib仅仅是列出了dll的导出符号而已。所以链接器只是想确认这个符号确实存在,以及这个符号来自哪个dll模块。
- 有关动态库总结!(19)
- 有关vc中使用动态链接库
- 有关turbo c编译动态库
- 动态库使用总结
- 有关动态库和静态库的生成和加载
- 有关加载动态链接库的一些东西
- 有关动态链接库的相关资料2:百科定义
- 2017.04.13 有关动态链接库的学习
- 有关语义搜索总结
- 有关字符串类型总结
- 有关jdbc的总结
- 有关const函数总结
- 有关服务器主程年总结
- memcached有关问题总结
- 有关输入的总结
- 有关spl的总结
- 有关动画的总结
- 有关maven的总结
- TensorFlow入门--安装常用的算法模块
- Git学习笔记五:Git分支管理策略
- Android的错误集合
- 今日头条频道管理(自带动画效果)
- 简化 ZXing 代码,策略模式自定义ViewfindView
- 有关动态库总结!(19)
- 递归和循环
- 表单标签-注册(类比搜狐)
- ==Tomcat的坑==【一切正常,就是连不上数据库,提示密码错误】。解决:先关闭Tomcat,再重启eclipse。老师说是Tomcat卡住了。
- IntelliJ IDEA使用(2)——IDEA配置Tomcat
- JavaWeb学习路线
- leetcode 137. Single Number II
- listview在主活动的oncreate方法中的使用案例
- Shell脚本:命令选项参数处理