昨天和同事使用一个dll(lib+dll)的时候,发现他在引用头文件是,并没有使用__declspec(dllimport),但是程序完全运行正常,不明觉厉下,去网上翻了下资料,原来是链接器的原因,这里贴一个转帖,已经写得很清楚了。

邓立波 深圳,2008-6

作者联系方式:

email:    libodeng@gmail.com

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)]

从上面可以看出,加上__declspec(dllimport),编译器链接dll将省略一条jmp语句。
这是因为:

1。如果导出函数的声明没有用__declspec(dllimport) 修饰的话,编译器并不知道这个函数是由DLL导出的,所以编译器就把这个函数当作普通的外部引用来对待,产生一个外部引用的符号等着链接器解析。当链接器工作的时候,它是不能修改编译器生成的结果,所以会将该符号解析为对相应函数调入节的间接调用。

2。如果导出函数的声明用__declspec(dllimport) 修饰的话,编译器一开始就知道这个函数是DLL导出函数,直接编译成对调入节的调用。

原文:http://libo.deng.blog.163.com/blog/static/40157422200851124138373/

最新文章

  1. 用递归调用实现字符串反转(java版)
  2. [Qcon] 百姓网开发总结
  3. Left Join 与Right Join 与 Inner Join 与 Full Join的区别
  4. [cocos2d-x·解Bug]关于cocos2d-x游戏在android锁屏状态下播放Bgm的解决方法
  5. pygame “音乐盒”---- 播放一首歌& 点击对话框后背景以及对话框大小改变
  6. MySQL相关知识
  7. Spring-boot使用Ehcache配置
  8. input标签文字点击变颜色
  9. Asp.Net MVC5入门学习系列②
  10. prototype原型解析
  11. kafka第四篇--快速入门(如何使用kafka)
  12. SpringBoot之彩色输出
  13. FCC学习笔记(一)
  14. 多项目管理中PMO的作用
  15. java第四章接口
  16. js异步编程终级解决方案 async/await
  17. DP 魔族密码 LIS
  18. Deepin 15.4 编译安装 LNMP(PHP 5.6.31 + Nginx 1.12.1 + MySQL 5.6.36)
  19. 查看SQL语句的真实执行计划
  20. 关于视觉跟踪中评价标准的相关记录(The Evaluation of Visual Tracking Results on OTB-100 Dataset)

热门文章

  1. java sqlite配置和自定义函数
  2. ReactiveCocoa入门教程——第一部分【转载】
  3. pycharm 5 注册码
  4. mac下spark单机环境配置笔记
  5. java的Access restriction错误
  6. python中的特殊用法
  7. 【AWS】亚马逊云常用服务解释
  8. 使用appium和testng实现Android自动截图
  9. Memcached的优点
  10. python获取本机IP地址