__declspec(dllimport) 和__declspec(dllexport)
2016-04-07 23:11
176 查看
__declspec(dllimport) 和__declspec(dllexport)
当链接dll的导出函数时,只需要包含头文件和lib,__declspec(dllimport)修饰符不是必须的,但是加上该修饰能使导出函数的调用效率更高,原因如下:不使用 __declspec(dllimport)也能正确编译代码,但使用 __declspec(import)使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于DLL中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨DLL边界的函数调用中。但是,必须使用__declspec(dllimport)才能导入DLL中使用的变量。
假设dll导出了一个函数:
extern “C” __declspec(dllexport) void fun();
一、如果程序中声明不加__declspec(dllimport),查看调用fun()函数的汇编代码:
004010AD call fun(004010d8)
其中fun被定义为一个标号(label),如下:
fun:
004010D8 jmp dword ptr[__imp__fun(0040e0e8)]
上面的符合__imp__fun指向地址为fun函数的exe中的导入节。
上当声明加上__declspec(dllimport)后,查看调用fun()函数的汇编代码:
004010AD call dwor ptr[__imp_fun(0040e0e8)]
从上面可以看出,加上__declspec(dllimport),编译器链接dll讲省略一条jmp语句。
这是因为:
1.如果导出函数的声明没有用__declspec(dllimport)修饰的话,编译器并不知道这个函数是由DLL导出,所以编译器把这个函数当做普通的外部引用来对待,产生一个外部引用的符号等着链接器解析。当链接器工作的时候,它是不能修改编译器生成的结果,所以会将该符号解析为对相应函数入节的间接调用。
2.如果导出函数的声明调用__declspec(dllimport)修饰的话,编译器一开始就知道这个函数是DLL导出函数,直接编译成对调入节的调用。
一般.h文件里是按照如下方式写:
SimpleDllClass.h #ifdef SIMPLEDLL_EXPORT #define DLL_EXPORT __declspec(dllexport) #else #define DLL_EXPORT __declspec(dllimport)
这样在只要DLL库实现的文件里 可以#define SIMPLEDLL_EXPORT,在调用的文件里就不需要定义该宏。包含这个.h,在class前面加DLL_EXPORT,就代表不同的含义,这是一个非常秒的写法。
相关文章推荐
- Nyoj Arbitrage(Floyd or spfa or Bellman-Ford)
- Android自定义控件系列八:详解onMeasure()(二)--利用onMeasure测量来实现图片拉伸永不变形,解决屏幕适配问题
- leetcode_084 Largest Rectangle in Histogram
- ML实验-KNN(续)
- 一天一命令 <cp\find\du>
- Spark如何使用Akka实现进程、节点通信的简明介绍
- LeetCode 74. Search a 2D Matrix
- 毕设第一天开发
- 【python学习】django安装,第一个应用
- android文件处理
- 购物车-----ListView 中CheckBox混乱
- 社区发现数据集
- HDU 4568 (SPFA 状压DP)
- LeetCode(35)-Path Sum
- LeetCode(35)-Path Sum
- LeetCode(35)-Path Sum
- HDU 4417 Super Mario 主席树
- SASS的简单运用,css更快
- hdoj1180 诡异的楼梯
- java 遍历map 方法