你好我现在对DLL有点困惑所以我来这里询问编程中有哪些专业人士 所以我得到了这个名为GUI.h的类和GUI.cpp
class GUI
{
public:
GUI(void);
virtual ~GUI();
void Draw(float x,float y,float z);
void Texture(int num);
bool Shutdown();
void TextureON(int num);
void TextureOFF(int num);
private:
GUIWeapon * Weapon;
GUIWeaponA * Weapona;
GUIArrow * Arrow;
GUIHP * hp;
GUIStop * stop;
GUISpeed * Speed;
float XCam,YCam,ZCam;
bool DrawStop;
};
所以我如何将其导出到DLL我已经制作了DLL而不是类,所以我是如何声明构造函数,析构函数并调用其他头文件中的其他GUIFunction?
答案 0 :(得分:2)
您没有指定编译器或操作系统,但如果这是Windows和Microsoft C ++,则可以在类上使用__declspec(dllexport)从DLL导出它。然后,当您包含要在其他地方使用的标头时,在同一个类上使用__declspec(dllimport)。
但是,我倾向于建议不要从DLL导出类。如果所有的DLL总是一起发送并且一起构建,那么这是一个好的计划。 [DLL只用于延迟加载代码]。如果您使用DLL来提供单独提供的实际组件,则应使用类似COM的实际可版本化抽象。
马丁
答案 1 :(得分:1)
像这样导出:
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中的sizeof
类和客户端(EXE)必须相同。例如,您可能会遇到一个SOME_SIZE数组,该数组被定义为宏。在DLL中,它可能是100
但在EXE中它可能是200
(出于任何原因)。这会破坏类,当你调用某个函数时this
指针是正确的;但不是班级(这意味着sizeof(GUI-in-DLL) != sizeof(GUI-in-EXE)
。
导出类也意味着公开包含它的所有数据成员。这将意味着暴露所有其他类/结构/ typedef / private变量等。对于解决方案,可以计算所有数据成员的大小(比如154字节),并在类declration中声明char filler[154]
(用于隐藏实际数据)。
虽然这实际上可行,但编译器链接器,调试器等不会有任何问题 - 但对程序员来说不灵活。
无论您是否使用填充字节隐藏实际数据声明,您还必须确保#pragma packing。首先,如果DLL有4个字节打包,并且EXE有(甚至错误)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实例分配指针,并将函数转发给该类。