将类导出到dll

exporting classes to DLLs

本文关键字:dll      更新时间:2023-10-16

你好,我现在对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,但不带类,所以我该如何声明构造函数,Destructor并在其他头中调用其他gufunctions ?

你不指定编译器或操作系统,但如果这是Windows和Microsoft c++,那么你可以在类上使用__declspec(dllexport)从DLL导出它。然后,当您包含要在其他地方使用的头文件时,在同一个类上使用__declspec(dllimport)。

然而,我倾向于不建议从dll导出类。如果所有dll总是一起发布并一起构建,那么这是一个不错的计划。[DLL只是用来延迟代码的加载]。如果您使用dll来提供单独发布的实际组件,则应该使用实际的可版本化抽象,如COM。

Martyn

导出:

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和它的客户端都有一个头文件。

但重要的是要注意DLL中的sizeof类和客户端(EXE)必须相同。例如,您可能有一个SOME_SIZE的数组,它被定义为宏。在DLL中,它可能是100,但在EXE中它可能是200(无论出于何种原因)。这只会破坏类,当你调用一些函数时,this指针将是正确的;但不是类(这意味着sizeof(GUI-in-DLL) != sizeof(GUI-in-EXE)

导出类还意味着公开类中包含的所有数据成员。这将意味着公开所有其他类/结构/类型定义/私有变量等等。对于解决方案,可以计算所有数据成员的大小(例如154字节),并在类声明中声明char filler[154](用于隐藏实际数据)。虽然这将实际工作,编译器链接器,调试器等不会有任何问题-但不灵活的程序员。

不管你是否用填充字节隐藏实际的数据声明,你还必须确保#pragma打包。首先,如果DLL有4个字节的打包,而EXE有(甚至是错误的)1个字节的打包,你就完全混乱了。而且这个错误/bug很难被发现!

在我看来,最好的解决方案是导出一个具有指针的类,该指针指向实现实际功能的类。这意味着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! ... 
};

这显然需要你分配指针与gu_internal的实例,并将函数转发给该类。

相关文章:
  • 没有找到相关文章