VC++ __declspec(dllexport) 和 __declspec(dllimport)

头文件中声明了方法,在提供者那里方法应该被声明为__declspec(dllexport),在使用者那里,方法应该被声明为__declspec(dllimport)

Class中含有一个静态变量,生成dll的时候只采用了__declspec(dllexport), 使用的时候__declspec(dllimport)就派上用场了,他会告诉使用dll的工程去lib中找到这个静态变量的定义。


加载一个dll时,其实你的程序是运行在两个独立空间的(dll的空间和你自己的程序空间),dll的对象模型其实相当严格,要访问dll空间的变量和函数,必须导出他们,否则这些对象是不可见的。这可以通过加入一个def文件,或者在声明中使用__declspec(dllimport)前缀,告诉编译器以下这些变量和函数是从dll导出的。同时定义这些变量的dll源文件必须加上__declspec(dllexport)前缀,告诉编译器这些函数需要被导出。

对类对象来说,静态成员函数必须加上这个前缀,因为这些对象都是在dll空间内的。在类的前面加上这些前缀就对整个类的成员进行了声明。这样在你的dll工程中定义__DLLEXPORT_IMP,__DLLEXPORT就会根据不同的工程转换成相应的前缀声明了。如果不加入这些前缀,链接会出现找不到符号的错误,因为这些符号在lib文件中被隐藏了。

使用虚函数导出(不使用_declspec(dllexport) / _declspec(dllimport))

导出类是一个派生类,派生自一个抽象类——都是纯虚函数。使用者需要知道这个抽象类的结构。DLL最少只需要提供一个用于获取类对象指针的接口。使用者跟DLL提供者共用一个抽象类的头文件,使用者依赖于DLL的东西很少,只需要知道抽象类的接口,以及获取对象指针的导出函数,对象内存空间的申请是在DLL模块中做的,释放也在DLL模块中完成,最后记得要调用释放对象的函数。

这种方式通用,产生的DLL没有特定环境限制。借助了C++类的虚函数。一般都是采用这种方式。除了对DLL导出类有好处外,采用接口跟实现分离,可以使得工程的结构更清晰,使用者只需要知道接口,而不需要知道实现。




posted @   double64  阅读(136)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示