1

hello im a bit confused with DLLs right now so i came here to ask where there are alot of pros in programming so ive got this class called GUI.h and the 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;

};

so how am i suppossed to export this to a DLL i have made DLLs but not with classes so how am im suppossed to declare the Constructor,Destructor and call the other GUIFunctions in other headers?

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
Makenshi
  • 993
  • 3
  • 15
  • 28

2 Answers2

2

You don't specify a compiler or operating system, but if this is Windows and Microsoft C++, then you can use __declspec(dllexport) on a class to export it from a DLL. You then use __declspec(dllimport) on the same class when you include the header to be consumed elsewhere.

However, I tend to recommend against exporting classes from DLLs. It's an ok plan if all the DLLs always ship together and are built together. [Where the DLL is just used to delay loading of code]. If you are using DLLs to provide actual components that ship separately, you should use an actual versionable abstraction like COM.

Martyn

Martyn Lovell
  • 2,086
  • 11
  • 13
1

Export like this:

class __declspec(dllexport) GUI 
{...}

Import like this:

class __declspec(dllimport) GUI 
{...}

Or simply define a macro like this:

#if _DEFINE_THIS_IN_YOUR_DLL_
    #define CLASS_IMPORT_EXPORT __declspec(dllexport)
#else
    #define CLASS_IMPORT_EXPORT __declspec(dllexport)
#endif

And directly use it:

class CLASS_IMPORT_EXPORT GUI
{
};

Be sure to have SINGLE header file for both DLL and its clients.

But it important to note that you sizeof class in DLL and the client (EXE) must be same. It may happen, for example, that you have an array of SOME_SIZE which is defined as macro. In DLL, it might be 100 but in EXE it might be 200 (for whatsoever reason). This would just break the class, when you call some function the this pointer would be correct; but not the class (that means sizeof(GUI-in-DLL) != sizeof(GUI-in-EXE).

Exporting a class also means exposing all of the data members included it it. This would mean exposing all other classes/structures/typedef/private variables and so on. For the solution, one might calculate the size of all data-members (say 154 bytes), and declare a char filler[154] in class declration (for hiding actual data). While this would practically work, compiler linker, debugger etc would not have any issues - but not flexible for programmer.

Irrespective if you hide the actual data declaration with filler-bytes or not, you must also ensure #pragma packing. For one, if DLL is having 4 bytes packing, and EXE is having (even by mistake) 1 byte packing, you are in total mess. And this mistake/bug is hard to detect!

The best solution, IMO, is to export a class having a pointer to class that implements the actual functionality. This means GUI_Internal/GUI_Core and exporting just GUI having pointer of either of these classes:

class IMPORT_EXPORT GUI
{
   GUI_Internal* pInternal; // 4/8 bytes only! EXACT
   // ... Export functions
};

But this would require the client-of-DLL (at compiler level) to know what GUI_Internal is. For this, just have a typedef:

#if _DEFINE_THIS_IN_YOUR_DLL_
typedef GUI_Internal* ClassPointer;
#else
typedef void* ClassPointer
#endif

and use it:

class CLASS_IMPORT_EXPORT GUI 
{ 
ClassPointer pointer; // Name is something else! ... 
};

This obviously requires you to allocate pointer with instance of GUI_Internal, and forward functions to that class.

Ajay
  • 18,086
  • 12
  • 59
  • 105