昨天和同事使用一个dll(lib+dll)的时候,发现他在引用头文件是,并无使用__declspec(dllimport),可是程序彻底运行正常,不明觉厉下,去网上翻了下资料,原来是连接器的缘由,这里贴一个转帖,已经写得很清楚了。函数
邓立波 深圳,2008-6spa
做者联系方式:blog
email: libodeng@gmail.comget
msn: libodeng@gmail.com编译器
按照MSDN说明,当连接dll的导出函数时,只须要包含头文件和lib,__declspec(dllimport)修饰符不是必须的,但加上该修饰能使导出函数的调用效率更高。那么,究竟缘由是什么?编译
假设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()函数的汇编代码:
004010AB call dword ptr [__imp__fun (0040e0e8)]email
从上面能够看出,加上__declspec(dllimport),编译器连接dll将省略一条jmp语句。
这是由于:import
1。若是导出函数的声明没有用__declspec(dllimport) 修饰的话,编译器并不知道这个函数是由DLL导出的,因此编译器就把这个函数看成普通的外部引用来对待,产生一个外部引用的符号等着连接器解析。当连接器工做的时候,它是不能修改编译器生成的结果,因此会将该符号解析为对相应函数调入节的间接调用。引用
2。若是导出函数的声明用__declspec(dllimport) 修饰的话,编译器一开始就知道这个函数是DLL导出函数,直接编译成对调入节的调用。
原文:http://libo.deng.blog.163.com/blog/static/40157422200851124138373/