declspec(dllexport)与_declspec(dllimport) 异同
2010-11-08 18:51
1 _declspec(dllexport)与_declspec(dllimport)
都是DLL内的关键字,即导出与导入。他们是将DLL内部的类与函数以及数据导出与导入时使用的。主要区别在于,dllexport是在这些类、函数以及数据的申明的时候使用。用过表明这些东西可以被外部函数使用,即(dllexport)是把DLL中的相关代码(类,函数,数据)暴露出来为其他应用程序使用。使用了(dllexport)关键字,相当于声明了紧接在(dllexport)关键字后面的相关内容是可以为其他程序使用的。而dllimport关键字是在外部程序需要使用DLL内相关内容时使用的关键字。当一个外部程序要使用DLL内部代码(类,函数,全局变量)时,只需要在程序内部使用(dllimport)关键字声明需要使用的代码就可以了,即(dllimport)关键字是在外部程序需要使用DLL内部相关内容的时候才使用。(dllimport)作用是把DLL中的相关代码插入到应用程序中。
  _declspec(dllexport)与_declspec(dllimport)是相互呼应,只有在DLL内部用dllexport作了声明,才能在外部函数中用dllimport导入相关代码。实际上,在应用程序访问DLL时,实际上就是应用程序中的导入函数与DLL文件中的导出函数进行链接。而且链接的方式有两种:隐式迎接和显式链接。
  隐式链接是指通过编译器提供给应用程序关于DLL的名称和DLL函数的链接地址,面在应用程序中不需要显式地将DLL加载到内存,即在应用程序中使用dllimport即表明使用隐式链接。不过不是所有的隐式链接都使用dllimport

  显式链接刚同应用程序用语句显式地加载DLL,编译器不需要知道任何关DLL的信息。

2

当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类。但是,MSDN文档里面,对于__declspec(dllimport)的说明让人感觉有点奇怪,先来看看MSDN里面是怎么说的:

“不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。”

编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。
     初看起来,这段话前面的意思是,不用它也可以正常使用DLL的导出库,但最后一句话又说,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量这个是什么意思??

那我就来试验一下,假定,你在DLL里只导出一个简单的类,注意,我假定你已经在项目属性中定义了 #define SIMPLEDLL_EXPORT

SimpleDLLClass.h 文件

#ifdef SIMPLEDLL_EXPORT
#define DLL_EXPORT __declspec(dllexport)//export 被选中
#else
#define DLL_EXPORT
#endif
class DLL_EXPORT SimpleDLLClass
{
public:
SimpleDLLClass();
virtual ~SimpleDLLClass();
virtual getValue() { return m_nValue;};//内联函数
private:
int m_nValue;
};

SimpleDLLClass.cpp 文件

#include "SimpleDLLClass.h"
SimpleDLLClass::SimpleDLLClass()
{
m_nValue=0;
}
SimpleDLLClass::~SimpleDLLClass()
{
}

然后你再使用这个DLL类,在你的APP中include SimpleDLLClass.h时,你的APP的项目不用定义 SIMPLEDLL_EXPORT 所以,DLL_EXPORT 就不会存在了,这个时候,你在APP中,不会遇到问题。这正好对应MSDN上说的__declspec(dllimport)定义与否都可以正常使用。但我们也没有遇到变量不能正常使用呀。 那好,我们改一下SimpleDLLClass,把它的m_nValue改成static,然后在cpp文件中加一行
int SimpleDLLClass::m_nValue=0;
如果你不知道为什么要加这一行,那就回去看看C++的基础。

改完之后,再去LINK一下,你的APP,看结果如何, 结果是LINK告诉你找不到这个m_nValue。明明已经定义了,为什么又没有了?? 肯定是因为我把m_nValue定义为static的原因。但如果我一定要使用Singleton的Design Pattern的话,那这个类肯定是要有一个静态成员,每次LINK都没有,那不是完了? 如果你有Platform SDK,用里面的Depend程序看一下,DLL中又的确是有这个m_nValue导出的呀。再回去看看我引用MSDN的那段话的最后一句。 那我们再改一下SimpleDLLClass.h,

把那段改成下面的样子:
#ifdef SIMPLEDLL_EXPORT
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
再LINK,一切正常。原来dllimport是为了更好的处理类中的静态成员变量的,如果没有静态成员变量,那么这个__declspec(dllimport)无所谓。

declspec(dllexport)与_declspec(dllimport) 异同相关推荐

  1. _declspec(dllexport)与_declspec(dllimport)

    __declspec(dllexport)2009-03-04 17:25 我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文 ...

  2. 学习编写测试桩之declspec (dllexport)篇

    动态库不能直接运行,也不能接受消息,他提供一些函数供执行他的程序或者动态库调用. windows API中的所有函数都包含在DLL中,其中有几个最为重要:Kernel32.dll,用户管理内存.进程和 ...

  3. 【DLL的函数】关于DLL的函数|_declspec(dllimport)

    目录 关于DLL的函数 _declspec(dllimport) 关于DLL的函数 2012-09-24 21:26:53 动态链接库中定义有两种函数:导出函数(export   function)和 ...

  4. 从static变量导出问题解析 __declspec(dllexport) 和 __declspec(dllimport)的作用

    这段时间要把tinyxml从静态库弄成动态库,要用到__declspec(dllexport)和__declspec(dllimport)来导出dll和lib文件.终于弄明白了export和impor ...

  5. 再写dll 关于declspec(dllexport)和declspec(dllimport)

    使用api 要先懂得怎么使用dll文件: 1.新建一个常规dll //dll.h #ifndef DLL_H #define DLL_H #ifdef DLL_EXPORTS #define DLLE ...

  6. 【_declspec(dllimport)】_declspec(dllimport)

    我的理解: dll 输出函数 就是dll中定义的,提供给调用dll的程序使用的函数. dll 输入函数 就是dll 中调用的 API中的函数 dll 输出函数是什么意思 检举  | 2011-12-1 ...

  7. 【转】extern “C“和__declspec(dllexport)以及__declspec(dllimport) 和def的简单解析

    转自:https://blog.csdn.net/xupan_jsj/article/details/9028759 前面的extern "C"  __declspec(dllex ...

  8. __declspec(dllexport)、__declspec(dllimport)详解

    在Visual studio中新建DLL项目时编译器会自动生成下面这样的宏定义: #ifdef DLL_EXPORTS #define DLL_API __declspec(dllexport) #e ...

  9. extern C和__declspec(dllexport)以及__declspec(dllimport) 和def的简单解析

    前面的extern "C"  __declspec(dllexport)  __declspec(dllimport)都是用于函数或者变量,甚至类的声明的(可以把extern &q ...

最新文章

  1. 【python】 针对python3 下无法导入tkinter
  2. 日本各地方与所属各县名称及其读音
  3. STM32F4 HAL库开发 -- USB U盘
  4. Nacos配置管理-Nacos实现配置管理
  5. java datatable用法_Java中实现DataTable工具类,并利用其实现简单分页控件。
  6. php有意思的小程序,这应该是迄今为止最全的小程序Top 100 榜单了,php中文网诚意奉上...
  7. android 手势输入法,基于触摸屏的手势输入法
  8. 多域名HTTPS 证书
  9. 二分查找之第一个大于小于等于 target 的值
  10. python报错:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xa3 in position 48
  11. 乘新能源汽车产业发展东风,智能网联驶入快车道
  12. Debian与Ubuntu到底有什么不同,应该如何选择?
  13. 在线客服 上下滚动 qq 简单明了 绝对不会报错 大众的选择 在线客服qq
  14. RDA5981开发环境安装
  15. STM32F407多路串口通信进行数据收发
  16. Centos7虚拟机磁盘恢复
  17. android 电视安装apk文件夹,智能电视无法识别apk文件怎么办?简单几招教你搞定...
  18. C语言的 “四大名著“ !书不在多、新、厚,有神则明!
  19. 如何根据单号批量查询德邦快递的物流信息
  20. Matlab:实现冲压发动机确定传热质量流量冲压发动机燃烧室(附完整源码)

热门文章

  1. 最好js代码验证×××号码
  2. 一名普通程序员的自我诊断书
  3. 2009.09.01 博客近期改进公告!
  4. NET许可证及License
  5. hdu 5624 KK's Reconstruction(最小生成树)
  6. hdu 3874(树状数组+离线算法)
  7. 论文阅读: Direct Monocular Odometry Using Points and Lines
  8. Spring Boot修改内置Tomcat端口号
  9. 《第一行代码》学习笔记9-活动Activity(7)
  10. 【编程题目】对称子字符串的最大长度 ★