在ObjectARX的类定义中使用__declspec(dllimport)的危险

在一个准备导出到其它应用中的类(Class)上使用__declspec(dllimport)指令时,会导致虚函数表(vtables)驻留在所有实例化过该类的dll中。
如果任何一个实例化过该类的dll被卸载,所有在该dll中创建的实例都会失效。随后访问这些失效实例的虚函数时就会导致内存错误。
因此,唯一安全地使用这个指令的办法,就是强制要求任何实例化过该类的应用都不允许卸载。
为了确保这一要求,你必须要么在文档中明确说明,或者提供一个伪构造函数驻留在无法被卸载的dll中。
最好的方法就是避免使用这个指令
唯一的例外就是如果这个类(Class)导出了一个静态成员变量。
在这种情况下你应该只在这个变量上使用__declspec(dllimport) ,但是你应该避免把它应用到整个class。但是我们不推荐导出静态成员变量。
本警告仅限于 __declspec(dllimport),它并不适用于__declspec(dllexport).
建议的用法如下所示:

#pragma warning( disable: 4275 4251 )
#ifdef POLYSAMP
#define DLLIMPEXP __declspec( dllexport )
#else
#define DLLIMPEXP
#endif

// The "DLLIMPEXP" is only required for exporting a poly API or using
// the exported API.  It is not necessary for any custom classes that
// are not exporting an API of their own.
//
class DLLIMPEXP AsdkPoly: public  AcDbCurve
{
public:
    ACRX_DECLARE_MEMBERS(AsdkPoly);
//*****************************************************************
// Constructors and destructor
//*****************************************************************

实际应用中,除非不使用该Class,否则无法只对静态成员变量使用__declspec(dllimport)
附:__declspec(dllimport)的主要用法:
1. 在导入动态链接库中的全局变量
2. 导出类的静态成员
3.隐式使用dll时,在生成的二进制代码上效率有所提高,可以节省一个跳转指令。

MSDN里的解释:

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

参考资料:
http://blog.csdn.net/mniwc/article/details/7993361
http://blog.csdn.net/Repeaterbin/article/details/4269666

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值