__declspec(dllexport)与__declspec(dllimport)
2015-09-01 14:32
302 查看
使用__declspec(dllexport)
从DLL导出
Microsoft在Visual 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
使用__declspec(dllexport)
从DLL导出
Microsoft在Visual 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
相关文章推荐
- git 相关资源
- 短信轰炸机
- Warning: The Copy Bundle Resources build phase contains this target's Info.plist file 'Info
- iOS开发支付宝支付,如何判断手机上面是否有安装支付宝软件
- Math.sqrt
- Memcache
- eclipse如何导出WAR包
- 再谈QVector与std::vector——使用装饰者让std::vector支持连续赋值
- PHP常见错误整理
- 我的openwrt学习笔记(二十六):smartconfig一键配置udp原理
- PS制作透明的BMP图片
- 免费的编程中文书籍索引
- 统一addEventListener与attachEvent中this指向问题
- eclipse自动部署web项目时WEB-INF\lib目录下缺少maven依赖jar包
- Macbook蓝牙不见了怎么办?
- iOS之 coredata
- [leetcode-4]Median of Two Sorted Arrays(c)
- 捞鱼问题
- 黑马程序员--Java常见对象
- 创建PostGIS数据库