将类导出到DLL

时间:2011-07-08 06:39:20

标签: c++ dll

你好我现在对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?

2 个答案:

答案 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实例分配指针,并将函数转发给该类。