出口是这样的:
class __declspec(dllexport) GUI
{...}
导入这样的:
class __declspec(dllimport) GUI
{...}
或者干脆这样定义一个宏:
#if _DEFINE_THIS_IN_YOUR_DLL_
#define CLASS_IMPORT_EXPORT __declspec(dllexport)
#else
#define CLASS_IMPORT_EXPORT __declspec(dllexport)
#endif
,并直接使用它:
class CLASS_IMPORT_EXPORT GUI
{
};
确保DLL和它的客户端都具有SINGLE头文件。
但重要的是要注意,您在DLL和客户端(EXE)中的类sizeof
必须相同。例如,可能会发生这样的情况:您有一个被定义为宏的SOME_SIZE数组。在DLL中,它可能是100
,但在EXE中它可能是200
(无论出于何种原因)。这只会打破课程,当你调用一些函数this
指针将是正确的;但不是类(这意味着sizeof(GUI-in-DLL) != sizeof(GUI-in-EXE)
。
导出类也意味着暴露所有包含它的数据成员,这意味着暴露所有其他类/结构/ typedef /私有变量等等。对于解决方案,可以计算所有数据成员的大小(比如说154个字节),并在类declration中声明一个char filler[154]
(用于隐藏实际数据) 尽管这实际上可行,但编译器链接器,调试器等不会有任何问题 - 但不会对于程序员来说是灵活的
不管你是否使用填充字节来隐藏实际的数据声明,还必须确保#pragma打包,例如,如果DLL有4个字节的打包,而EXE正在ake)1个字节的打包,你是一团糟。而这个错误/错误很难被发现!
IMO的最佳解决方案是导出一个具有指向实现实际功能的类的指针的类。这意味着GUI_Internal
/GUI_Core
和出口只是GUI
具有这两种类别的指针:
class IMPORT_EXPORT GUI
{
GUI_Internal* pInternal; // 4/8 bytes only! EXACT
// ... Export functions
};
但这需要客户的-DLL(编译时的水平),知道什么是GUI_Internal
。对于这一点,只是有一个typedef
:
#if _DEFINE_THIS_IN_YOUR_DLL_
typedef GUI_Internal* ClassPointer;
#else
typedef void* ClassPointer
#endif
,并使用它:
class CLASS_IMPORT_EXPORT GUI
{
ClassPointer pointer; // Name is something else! ...
};
显然,这需要你有GUI_Internal的实例,并转发功能,该类分配指针。
http://msdn.microsoft.com/en-us/library/ms235636(v=vs.80).aspx –
我宁愿提供一个C接口。更容易使用。 – Calmarius