转自:http://www.cppblog.com/Dutyboy/archive/2010/11/15/133699.html

__declspec(dllexport)  

__declspec(dllexport)    将一个函数声名为导出函数,就是说这个函数要被包含她的程序之外的程序调用。   
extern    "C"                    指示编译器用C语言方法给函数命名。   
       在制作DLL导出函数时由于C++存在函数重载,因此__declspec(dllexport)    function(int,int)    在DLL会被decorate,例如被decorate成为    function_int_int,而且不同的编译器decorate的方法不同,造成了在用GetProcAddress取得function地址时的不便,使用extern    "C"时,上述的decorate不会发生,因为C没有函数重载,但如此一来被extern"C"修饰的函数,就不具备重载能力,可以说extern    和   extern    "C"不是一回事。

__declspec(dllimport)

我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类。但是,MSDN文档里面,对于__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)定义与否都可以正常使用。但我们也没有遇到变量不能正常使用呀。 那好,我们改一下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)的区别

    最近看MXNet的源码,其中c_api.h中发现遇到__declspec(dllexport) 和 __declspec(dllimport). __declspec(dllexport)用于导出符号 ...

  2. __declspec(dllexport)和__declspec(dllimport) (——declspec方法创建dll的方法已验证ok)

    转载:https://www.cnblogs.com/chengbing2011/p/4084125.html __declspec(dllimport)和__declspec(dllexport)经 ...

  3. 浅谈__declspec(dllexport)和__declspec(dllimport)

    __declspec(dllimport)和__declspec(dllexport)经常是成对的,在动态链接库中__declspec(dllexport)导出dll中的成员,__declspec(d ...

  4. 理解 __declspec(dllexport)和__declspec(dllimport)

    1.解决的问题: 考虑下面的需求,使用一个方法,一个是提供者,一个是使用者,二者之间的接口是头文件.头文件中声明了方法,在提供者那里方法应该被声明为__declspec(dllexport),在使用者 ...

  5. __declspec(dllexport) 和 __declspec(dllimport)的作用

    operatordll.h #include <iostream> #ifndef _WIN32 #define DLL_EXPORT#else #ifdef OPERATORDLL_EX ...

  6. 通过宏定义将__declspec(dllexport)与__declspec(dllimport)的转化,实现库代码和使用代码使用同一份头文件

    我们知道,在VC编程中,如果要编译成动态链接库,需要将函数.变量.类等导出,这时使用__declspec(dllexport).使用动态链接库时,需要在声明的时候有使用__declspec(dllim ...

  7. __declspec(dllexport)

    __declspec(dllexport) (2010-06-17 10:04:28) 转载▼ 标签: __declspec dllexport 导出 it 分类: C 先看代码:以下是在dev-c+ ...

  8. 【转载】extern "C" __declspec(dllexport) __declspec(dllimport) 和 def

    转自:http://www.cppblog.com/FateNo13/archive/2009/08/03/92052.html 前面的extern "C"  __declspec ...

  9. extern "C" __declspec(dllexport) __declspec(dllimport) 和 def

    原文:extern "C" __declspec(dllexport) __declspec(dllimport) 和 def 前面的extern "C"  _ ...

随机推荐

  1. win10创建本地用户

    win+r,输入lusrmgr.msc win+i

  2. 吴裕雄--天生自然 HADOOP大数据分布式处理:安装XShell

    下载安装包

  3. Wannafly Winter Camp 2020 Day 6J K重排列 - dp

    求 \(K\) 是多少个 \(n\) 元置换的周期.\(T\leq 100, n\leq 50, K \leq 10^{18}\) Solution 置换可以被试做若干个环组成的有向图,于是考虑 dp ...

  4. MySQL系列(一):谈谈MySQL架构

    MySQL整体架构 与所有服务端软件一样,MySQL采用的也是C/S架构,即客户端(Client)与服务端(Server)架构,我们在使用MySQL的时候,都是以客户端的身份,发送请求连接到运行服务端 ...

  5. webpack4从安装到使用入过的那些坑

    1.全局安装 安装 webpack 前要确保已经下载 node.js 最新版本(node.js官网地址) 目前使用命令行安装的 webpack 默认为最新版本(以下我使用了全局安装.官网建议本地安装, ...

  6. web攻击与防御

    攻击方式 利用输出值转义漏洞 跨站脚本攻击(XSS) SQL注入攻击 OS命令注入攻击 HTTP首部注入攻击 邮件首部注入攻击 文件目录遍历攻击 利用设置或设计缺陷 强制游览 开放重定向 不正确的错误 ...

  7. mysql引擎介绍

    mysql存储引擎介绍: 插拔式的插件方式 存储引擎是指定在表上的,即一个库中的每一个表都可以指定专用的存储引擎 不管采用什么样的存储引擎,都会在数据区产生对应的一个frm文件(表结构定义描述文件) ...

  8. Xamarin.Forms弹出对话框插件

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议,请网站留言: 如果您觉得Dotnet9对您有帮助,欢迎赞赏. Xamarin.Forms弹出对话框插件 内容目录 实现效果 业务场景 编码 ...

  9. Python之pptx实现添加内容与删除(移动)页操作

    问题背景 大量表格数据需要生成指定格式的ppt文件,内容以文字和表格为主,首尾页与内容有固定格式.博主不熟悉VBA操作,希望通过模板用Python完成自动化. 基本思路 使用xlrd模块读取xlsx文 ...

  10. Csla One or more properties are not registered for this type

    在实际运行中,好好运行的程序出现了以下问题: 2019-12-27 10:40:00,164 [DefaultQuartzScheduler_Worker-2] ERROR IBeam.BCPool. ...