2011-07-08 38 views
1

你好,現在我是一個有點混淆的DLL,所以我來這裏問問,那裏有很多編程 利弊所以香港專業教育學院得到這個類叫做GUI.h和GUI.cpp出口類的DLL

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; 

}; 

所以我如何suppossed導出到一個DLL我已經做了DLL但沒有類,所以我如何supp suppossed聲明構造函數,析構函數和調用其他頭文件中的其他GUIFunctions?

+0

http://msdn.microsoft.com/en-us/library/ms235636(v=vs.80).aspx –

+0

我寧願提供一個C接口。更容易使用。 – Calmarius

回答

1

您不指定編譯器或操作系統,但如果這是Windows和Microsoft C++,則可以使用__declspec(dllexport)類將其從DLL中導出。然後,當您將標頭包含在別處時,您可以在同一個類上使用__declspec(dllimport)。

但是,我傾向於建議不要從DLL導出類。如果所有的DLL總是一起發佈並且構建在一起,那麼這是一個好的計劃。 [DLL只用於延遲加載代碼]。如果您使用DLL來提供單獨發運的實際組件,則應使用像COM這樣的實際可版本化抽象。

馬丁

+0

好吧非常感謝你,我也反對它,但它真的是一個家庭作業即時通訊不做現在lol – Makenshi

+0

@Makenshi:然後下次使用作業標籤 –

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和客戶端(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的實例,並轉發功能,該類分配指針。