一、基本概念
_declspec(dllexport)与_declspec(dllimport)都是DLL内的关键字,即导出与导入。他们是将DLL内部的类与函数以及数据导出与导入时使用的。

主要区别在于:dllexport是在这些类、函数以 及数据的申明的时候使用。用过表明这些东西可以被外部函数使用,即(dllexport)是把DLL中的相关代码(类,函数,数据)暴露出来为其他应用程 序使用。而 dllimport关键字是在外部程序需要使用DLL内相关内容时使用的关键字。

二、初步理解
考虑下面的需求,使用一个方法,一个是提供者,一个是使用者,二者之间的接口是头文件。头文件中声明了方法,在提供者那里方法应该被声明为__declspec(dllexport),在使用者那里,方法应该被声明为__declspec(dllimport)。二者使用同一个头文件,作为接口,怎么办呢?

使用条件编译:定义一个变量,针对提供者和使用者,设置不同的值。
#ifndef DLL_H_  
#define DLL_H_  
  
#ifdef DLLProvider  
#define DLL_EXPORT_IMPORT __declspec(dllexport)  
#else  
#define DLL_EXPORT_IMPORT __declspec(dllimport)  
#endif  
 
DLL_EXPORT_IMPORT int add(int ,int);  
 
#endif

以上解释似乎可以说明_declspec(dllimport)存在的意义,但是在实际工程过程中慢慢发现,不用_declspec(dllimport),我们也可以将动态链接库进行导入使用,那么_declspec(dllimport)的作用究竟是什么??
三、深入剖析
先来看看MSDN里面的解释:
不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。
初看起来,这段话前面的意思是,不用它也可以正常使用DLL的导出库,但最后一句话又说,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量这个是什么意思??
试验一下,假定,你在DLL里只导出一个简单的类,注意,我假定你已经在项目属性中定义了 SIMPLEDLL_EXPORT
//SimpleDLLClass.h
 
#ifdef SIMPLEDLL_EXPORT
#define DLL_EXPORT __declspec(dllexport)
#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)定义与否都可以正常使用。但我们也没有遇到变量不能正常使用呀。
那好,1)我们改一下SimpleDLLClass,把它的m_nValue改成static。

2)然后在cpp文件中加一行:

int SimpleDLLClass::m_nValue=0;
 改完之后,再去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)是相互呼应,只有在DLL内部用dllexport作了声明,才能 在外部函数中用dllimport导入相关代码。实际上,在应用程序访问DLL时,实际上就是应用程序中的导入函数与DLL文件中的导出函数进行链接。而且链接的方式有两种:隐式链接和显式链接。
  隐式链接是指通过编译器提供给应用程序关于DLL的名称和DLL函数的链接地址,面在应用程序中不需要显式地将DLL加载到内存,即在应用程序中使用dllimport即表明使用隐式链接。不过不是所有的隐式链接都使用dllimport。
       显式链接即应用程序用语句显式地加载DLL,编译器不需要知道任何关DLL的信息。

关于__declspec(dllimport)的理解相关推荐

  1. 【转载】__declspec(dllimport) __declspec(dllexport)

    https://blog.csdn.net/fsdad/article/details/115632555 一.基本概念 _declspec(dllexport)与_declspec(dllimpor ...

  2. extern C __declspec(dllexport) __declspec(dllimport) 和 def

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

  3. (转)__declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定

    DLL可以使用两种方法将公共符号导入到应用程序中或从 DLL 导出函数: 生成 DLL 时使用模块定义 (.DEF) 文件.  在主应用程序的函数定义中使用 __declspec(dllimport) ...

  4. __declspec(dllimport)

    我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是C++的类的话 ...

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

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

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

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

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

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

  8. error LNK2019: unresolved external symbol “__declspec(dllimport) public: __thiscall 的解决方案

    error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall 的解决方案 参考文章: ...

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

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

最新文章

  1. Python爬虫之urllib和requests哪个好用--urllib和requests的区别
  2. uvc摄像头代码解析7
  3. 电脑运行慢的原因汇总
  4. python安装步骤3.7.2-linux环境安装python3.7.2
  5. saltstack (1) 简介
  6. 【Android 应用开发】 Android 相关代码规范 更新中 ...
  7. 让Visual Studio 2013为你自动生成XML反序列化的类
  8. Magnet for mac(窗口布局辅助工具)
  9. 数据结构:内排序(C++)
  10. 学习类App原型制作分享-Wokabulary
  11. 可以使用GPU暴力破解密码的软件
  12. 二层交换机与路由器的区别
  13. 升级macos beta_如何选择退出macOS开发人员或公开Beta版
  14. 什么是软件_什么是软件?
  15. Android7.0上拍照与选择照片Crash问题
  16. 印象笔记,为知笔记和Effie哪个更适合商业机构提案人员?
  17. 51单片机DAC数模转换
  18. linux当中shadow文件的作用,解释Linux中passwd与shadow文件
  19. Xilinx SDK使用
  20. srs可以用java开发吗,为SRS流媒体服务器添加HLS加密功能(附源码)

热门文章

  1. android mnt asec,通过adb修改Android etc下的vold.fstab,调测vold.fstab
  2. QeePHP框架学习
  3. 携程容器偶发性超时问题案例分析
  4. 常见的限流算法及其原理剖析
  5. 温室气体真会导致第六次生物大灭绝?
  6. portmap全网最稳定的端口转发工具
  7. FreeRTOS任务通知 基于STM32
  8. 情人节送礼荒?荣耀30Pro流光幻境了解一下
  9. W5500 图片嵌入STM32 FLASH笔记(备忘)
  10. Unity3d展厅模型预处理UV拆分光影烘焙材质及后处理与特效制作基本流程【2020】