__declspec(dllexport)与__declspec(dllimport)



使用__declspec(dllexport) DLL导出

MicrosoftVisual C++16位编译器版本中引入了__export,使编译器得以自动生成导出名,并将它们放到一个.lib文件中。然后此.lib文件就可以像静态.lib那样用于与DLL链接。在32位编译器版本中,可以使用__declspec(dllexport) 关键字从DLL导出数据、函数、类或类成员函数。__declspec(dllexport)会将导出指令添加到对象文件中,因此不需要使用.def文件。当试图导出C++修饰函数名时,这种便利最明显。由于对名称修饰没有标准规范,因此导出函数的名称在不同的编译器版本中可能有所变化。

如果使用__declspec(dllexport),仅当解决任何命名约定更改时才必须重新编译DLL和依赖.exe文件。 许多导出指令(如序号、NONAME PRIVATE)只能在.def文件中创建,并且必须使用.def文件来指定这些属性。不过,在.def文件的基础上另外使用__declspec(dllexport)不会导致生成错误。若要导出函数,__declspec(dllexport)关键字必须出现在调用约定关键字的左边(如果指定了关键字)。例如:

__declspec(dllexport) void__cdecl Function1(void);

若要导出类中的所有公共数据成员和成员函数,关键字必须出现在类名的左边,如下所示:

class__declspec(dllexport) CExampleExport : public CObject

{ ...class definition ... };

生成DLL时,通常创建一个包含正在导出的函数原型和/或类的头文件,并将 __declspec(dllexport)添加到头文件中的声明中。若要提高代码的可读性,请为 __declspec(dllexport)定义一个宏,并对正在导出的每个符号使用该宏:

#defineDllExport __declspec(dllexport)

__declspec(dllexport)将函数名存储在DLL的导出表中。如果希望优化表的大小,请参见按序号而不是按名称从 DLL 导出函数

DLL源代码从Win16移植到Win32时,请用__declspec(dllexport)替换__export的每个实例。作为参考,请在 Win32 Winbase.h 头文件中搜索。它包含 __declspec(dllimport) 的用法示例。

使用__declspec(dllimport) 导入到应用程序中 

如果一个程序使用DLL定义的公共符号,就说该程序是在导入公共符号。为使用DLL生成的应用程序创建头文件时,在公共符号的声明上使用__declspec(dllimport)。不论是用.def文件导出还是用__declspec(dllexport)关键字导出,__declspec(dllimport)关键字均有效。

若要提高代码的可读性,请为__declspec(dllimport)定义一个宏,然后使用此宏声明每个导入的符号:

#defineDllImport __declspec( dllimport )

DllImportint j;

DllImportvoid func();

在函数声明上使用__declspec(dllimport) 是可选操作,但如果使用此关键字,编译器将生成更有效的代码。但是,为了使导入的可执行文件能够访问DLL的公共数据符号和对象,必须使用__declspec(dllimport)。请注意:DLL的用户仍然需要与导入库链接。

DLL和客户端应用程序可以使用相同的头文件。为此,请使用特殊的预处理器符号来指示是生成DLL还是生成客户端应用程序。例如:

#ifdef_EXPORTING

   #define CLASS_DECLSPEC __declspec(dllexport)

#else

   #define CLASS_DECLSPEC __declspec(dllimport)

#endif

 

classCLASS_DECLSPEC CExampleA : public CObject

{ …class definition … };

__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的信息。

PS:MSDN上有相关的文档,有兴趣的读者可以参看:https://msdn.microsoft.com/zh-cn/library/1ez7dh12(v=vs.120).aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值