包不包含__declspec(dllimport)的判定
按照MSDN说明,当链接dll的导出函数时,只需要包含头文件和lib,__declspec(dllimport)修饰符不是必须的,但加上该修饰能使导出函数的调用效率更高。那么,究竟原因是什么?
不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 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()函数的汇编代码:
004010AB call dword ptr [__imp__fun (0040e0e8)]
从上面可以看出,加上__declspec(dllimport),编译器链接dll将省略一条jmp语句。
这是因为:
1。如果导出函数的声明没有用__declspec(dllimport) 修饰的话,编译器并不知道这个函数是由DLL导出的,所以编译器就把这个函数当作普通的外部引用来对待,产生一个外部引用的符号等着链接器解析。当链接器工作的时候,它是不能修改编译器生成的结果,所以会将该符号解析为对相应函数调入节的间接调用。
2。如果导出函数的声明用__declspec(dllimport) 修饰的话,编译器一开始就知道这个函数是DLL导出函数,直接编译成对调入节的调用。
最新文章
- druid sql黑名单 报异常 sql injection violation, part alway true condition not allow
- PostgreSQL 杂志
- ubuntu下deb包的安装方法
- POJ3208 Apocalypse Someday(二分 数位DP)
- 简单回忆一下JavaScript中的数据类型
- 源代码解读Cas实现单点登出(single sign out)功能实现原理
- TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
- GDI泄露检测
- Sql Server中三种字符串合并方法的性能比较
- 微信小程序hidden
- linux上部署rmi+memcache服务
- python3使用ctypes在windows中访问C和C++动态链接库函数示例
- python Socket socketserver
- LeetCode 520 Detect Capital 解题报告
- JavaScript如何实现继承
- 重写$.ajax方法
- nginx反向代理 支持WebSocket
- spring mvc 接受前台json @RequestBody json 属性 空 使用 JsonProperty spring mvc 获取json转乘bean
- 【Linux】字符转换命令paste
- netif_receive_skb->;__netif_receive_skb_core