包不包含__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导出函数,直接编译成对调入节的调用。
包不包含__declspec(dllimport)的判定的更多相关文章
- extern "C" __declspec(dllexport) __declspec(dllimport) 和 def
原文:extern "C" __declspec(dllexport) __declspec(dllimport) 和 def 前面的extern "C" _ ...
- 动态链接库(dll) __declspec(dllimport) __declspec(dllexport)
一. __declspec(dllexport) Microsoft 在 Visual C++ 的 16 位编译器版本中引入了 __export,使编译器得以自动生成导出名并将它们放到一个 .lib ...
- __declspec(dllimport)与__declspec(dllexport)作用总结
参考自:http://bbs.csdn.net/topics/330169671 __declspec(dllexport):导出符号,也就是定义需要导出函数的dll中给导出函数的函数声明前面加上导出 ...
- __declspec(dllexport) 和 __declspec(dllimport)的区别
最近看MXNet的源码,其中c_api.h中发现遇到__declspec(dllexport) 和 __declspec(dllimport). __declspec(dllexport)用于导出符号 ...
- __declspec(dllimport)的小秘密(转)
昨天和同事使用一个dll(lib+dll)的时候,发现他在引用头文件是,并没有使用__declspec(dllimport),但是程序完全运行正常,不明觉厉下,去网上翻了下资料,原来是链接器的原因,这 ...
- 【转载】extern "C" __declspec(dllexport) __declspec(dllimport) 和 def
转自:http://www.cppblog.com/FateNo13/archive/2009/08/03/92052.html 前面的extern "C" __declspec ...
- 【转载】 __declspec(dllexport) 和__declspec(dllimport)
转自:http://www.cppblog.com/Dutyboy/archive/2010/11/15/133699.html __declspec(dllexport) __declspec( ...
- VC++ : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall std::basic_string<wchar_t,struct std::char_traits<wchar_t>
最近学习Google Breakpad,将其用在了自己的项目中,编译的版本为VS2010,没有什么问题.但是为了和之前的程序兼容,需要使用VS2008版本的程序,于是又编译了VS2008版本的代码,但 ...
- __declspec(dllimport)
我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是C++的类的话 ...
随机推荐
- c#项目代码风格要求
代码风格没有正确与否,重要的是整齐划一,这是我拟的一份<.Net 项目代码风格要求>,供大家参考. 1. C# 代码风格要求 1.1注释 类型.属性.事件.方法.方法参数,根据需要添加注释 ...
- 四、spark集群架构
spark集群架构官方文档:http://spark.apache.org/docs/latest/cluster-overview.html 集群架构 我们先看这张图 这张图把spark架构拆分成了 ...
- linux的环境变量与文件查找
1. 环境变量 1.1 变量 shell 中的变量有不同类型,可参与运算,有作用域限定 变量的作用域即变量的有效范围(比如一个函数中.一个源文件中或者全局范围),在该范围内只能有一个同名变量.一旦离开 ...
- Struts2(一)— 入门
一.概述 1.什么是Struts2 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立 ...
- JSP九个内置对象及指令、动作标签
一.JSP九大内置对象 (一)JSP中无需创建就可以使用的9个对象 输入输出对象 1.response(HttpServletResponse):处理JSP生成的响应,然后将响应结果发送给客户端.是s ...
- Bzoj4766: 文艺计算姬(Matrix-tree/prufer)
BZOJ 答案就是 \(n^{m-1}m^{n-1}\) \(prufer\) 证明: \(n\) 中的数字出现 \(m-1\) 次,\(m\) 中出现 \(n-1\) 次,根据 \(prufer\) ...
- laravel之路由汇总
- Mongodb安装详解及mongochef视图工具安装。
按照国际惯例我们先来介绍一下MongoDB. MongoDB是一个基于分布式文件存储的数据库,由c++语言编写,为WEB应用提供可扩展的高性能数据存储解决方案.MongoDB属于非关系数据库,也不能说 ...
- JS判断客户端是手机还是PC的2个代码
搬了下砖 function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", & ...
- Leetcode算法比赛----Longest Absolute File Path
问题描述 Suppose we abstract our file system by a string in the following manner: The string "dir\n ...