当前位置: 首页 > news >正文

四川通信建设工程有限公司网站/做高端网站公司

四川通信建设工程有限公司网站,做高端网站公司,服务号微网站怎么做的,做网站常用代码__declspec(dllexport) & __declspec(dllimport) __declspec(dllexport) 声明一个导出函数,是说这个函数要从本DLL导出。我要给别人用。一般用于dll中 省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C的类的话,…
__declspec(dllexport) & __declspec(dllimport)

__declspec(dllexport)

声明一个导出函数,是说这个函数要从本DLL导出。我要给别人用。一般用于dll中
省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类

__declspec(dllimport)

声明一个导入函数,是说这个函数是从别的DLL导入。我要用。一般用于使用某个dll的exe中
不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。

 
使用举例:
  // File: 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;
};
 

// File: SimpleDLLClass.cpp

#include "SimpleDLLClass.h"

SimpleDLLClass::SimpleDLLClass()
{
 m_nValue=0;
}

SimpleDLLClass::~SimpleDLLClass()
{
}
 

说明:
1. 在你的APP中include SimpleDLLClass.h时,如果你的APP的项目不定义SIMPLEDLL_EXPORT,则DLL_EXPORT不存在。此时APP仍可以正常运行。

// File: SimpleDLLClass.h
static int m_nValue;

// File: SimpleDLLClass.cpp
int SimpleDLLClass::m_nValue=0;
 

说明:
1. 如果你的APP的项目不定义SIMPLEDLL_EXPORT,则DLL_EXPORT不存在。此时APP无法LINK。原因是找不到m_nValue。(原因:静态变量m_nValue已被DLL导出,但SimpleDLLClass无法访问m_nValue)
Workaround:
#define DLL_EXPORT __declspec(dllimport)

Conclusion:
dllimport是为了更好的处理类中的静态成员变量(或者其他...)的,如果没有静态成员变量(或者其他...),那么这个__declspec(dllimport)无所谓.

/

在Windows DLL编程时,可使用__declspec(dllimport)关键字导入函数或者变量。

函数的导入
当你需要使用DLL中的函数时,往往不需要显示地导入函数,编译器可自动完成。但如果你显示地导入函数,编译器会产生质量更好的代码。由于编译器确切地知道了一个函数是否在一个DLL中,它就可以产生更好的代码,不再需要间接的调用转接。
Win32的PE格式(Portable Executable Format)把所有导入地址放在一个导入地址表中。下面用一个具体实例说明使用__declspec(dllimport)导入函数和不使用的区别:
假设func是一个DLL中的函数,现在在要生成的.exe的main函数中调用func函数,并且不显示地导入func函数(即没有:__declspec(dllimport)),代码示例如下:
int main()
{
func();
}
编译器将产生类似这样的调用代码:
call func
然后,链接器把该调用翻译为类似这样的代码:
call 0x40000001       ; ox40000001是"func"的地址
并且,链接器将产生一个Thunk,形如:
0x40000001: jmp DWORD PTR __imp_func
这里的imp_func是func函数在.exe的导入地址表中的函数槽的地址。然后,加载器只需要在加载时更新.exe的导入地址表即可。
而如果使用了__declspec(dllimport)显示地导入函数,那么链接器就不会产生Thunk(如果不被要求的话),而直接产生一个间接调用。因此,下面的代码:
__declspec(dllimport) void func1(void);
   void main(void)
    {
        func1();
    }
将调用如下调用指令:
call DWORD PTR __imp_func1
因此,显示地导入函数能有效减少目标代码(因为不产生Thunk)。另外,在DLL中使用DLL外的函数也可以这样做,从而提高空间和时间效率。
变量的导入
与函数不同的是,在使用DLL中的变量时,需要显示地导入变量。使用__declspec(dllimport)关键字导入变量。若在DLL中使用.def导出变量,则应使用DATA修饰变量,而不是使用已经被遗弃的CONSTANT。因为CONSTANT可能需要使用指针间接访问变量,不确定什么时候会出问题。
//

我相信写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#endifclass 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)无所谓。

转载于:https://www.cnblogs.com/GT_Andy/archive/2011/05/10/2042203.html

http://www.lbrq.cn/news/1362367.html

相关文章:

  • 怎么提高网站的访客量/引擎搜索对人类记忆的影响
  • 如何在阿里云做网站/沈阳关键词推广
  • 设计网站behance/百度推广有效果吗
  • 一起做财经网站/长沙seo行者seo09
  • 网站优化怎样提高网站用户体验/找谁做百度关键词排名
  • 做个自己的网站需要多少钱/长春疫情最新消息
  • 企业网站建设的账务处理/安卓内核级优化神器
  • 重庆营销网站建设/最近三天的新闻大事摘抄
  • 安庆网站建设专业/竞价排名采用什么计费方式
  • 网站开发定制企业/怎么可以在百度发布信息
  • 银川网站建设培训哪家好/小说网站排名
  • 网站平台怎么建立/爱站网关键字挖掘
  • 做蓝牙音箱在什么网站上找客户/seddog站长之家
  • 化妆品公司网站源码/搜索引擎竞价排名
  • 中国企业网银怎么转账/seo关键词优化排名公司
  • 网站建设服务合同 律师/谷歌查询关键词的工具叫什么
  • 安州区建设局网站/爱站网 关键词挖掘
  • 淄博 网站seo优化/刷关键词指数
  • 如何给自己的公司网站做优化/线上营销渠道主要有哪些
  • 做网站电销/品牌策划公司哪家好
  • 说明书得制作需要哪些材料/南京关键词优化服务
  • 上海 网站建设/百度app官网下载
  • 福田皇岗社区网站建设/百度快速收录教程
  • 建设一个网站需要哪些方面的开支/百度免费推广方法
  • 网站模版怎么做/青岛网站seo分析
  • 美容美发网站建设方案/app推广方式
  • 如何制作境外网站/域名查询网
  • 一级a做爰精免费网站/百度竞价关键词优化
  • 建设电子商务网站需要什么设备/soe搜索优化
  • 网站内容包括/武汉seo网站优化技巧
  • 13015计算机系统原理-速记宝典
  • MySQL学习之MVCC多版本并发控制
  • 日常--详细介绍qt Designer常用快捷键(详细图文)
  • ThinkPHP5x,struts2等框架靶场复现
  • JavaEE初阶第十三期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(十一)
  • 关于Web前端安全防御之内容安全策略(CSP)