编程许久,在使用DLL导出类的时候,用的都是AFX_EXT_CLASS,直到近日,才终于发现这个家伙有点缺陷。
让我们来看这样一个问题:新建一个MFC Extension DLL ,并在其中新建一个类testA。
// testA.h
class AFX_EXT_CLASS testA
{
public:
testA();
virtual ~testA();
public:
static const double PI;
};
在头文件中声明了类静态变量PI,并在testA.cpp中进行了初始化。
const double testA::PI = 3.14;
编译通过,生成lib,dll.
试验发现:
如果客户是一般的exe程序,使用PI正常,编译通过。
如果客户是另一个DLL,使用PI的时候编译通过不了,报如下错误:
error LINK2001: unresolved external symbol ... PI ...
在网上找了好久,没有找到解决方案,只好用全局变量PI来代替,或者使用全局函数来返回PI的值,即
double GetPI()
{
return testA::PI;
}
有一天终于发现了解决办法:即采用普通的__declspec(dllexport)和__declspec(dllimport),而不采用AFX_EXT_CLASS
// testA.h
#ifdef SIMPLEDLL_EXPORT
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
class DLL_EXPORT testA
{
public:
testA();
virtual ~testA();
public:
static const double PI;
};
// testA.cpp
#define SIMPLEDLL_EXPORT
#include "testA.h
现在不管客户是EXE还是DLL,只需要包含testA.h, 使用PI正常。
可见问题就是在于AFX_EXT_CLASS了。
经过百般查证,终于找到了部分原因:
The problem is that in Win32, you must explicitly declare any data as _declspec(dllexport) if it is to be exported from a DLL, and declare any data as _declspec(dllimport) if it is to be imported from a DLL. When you define _AFXEXT, the MFC headers make sure that AFX_EXT_CLASS is defined correctly. When you have multiple layers, one symbol such as AFX_EXT_CLASS is not sufficient because an extension DLL may be exporting new classes as well as importing other classes from another extension DLL.
希望高手们能详细解释一下具体的原因。
以上实验在VS2008和VC6.0下通过。
评论