2015-10-16 104 views
0

我目前正在開發一款遊戲,分爲兩部分:引擎位於.dll,實際遊戲代碼是.exe的一部分。引擎和其他頭文件包含一個管理所有組件的範圍,從Win32特定對象到D3D11指針。這些組件包含在一個類中,允許它們通過返回對其引用的函數在全局訪問。而且,對於它管理的每個項目,都有兩個功能可以設置或返回組件。我還使用關鍵部分添加了線程保護。 所以,在State.h我:.dll中的C++ CRITICAL_SECTION對象給出無法解析的外部符號錯誤

#if defined(NF3D_NONCLIENT_BUILD) 
     #define NF3D_API __declspec(dllexport) 
    #else 
     #if defined(__MINGW32__) 
      #define NF3D_API NF3D_API 
     #else 
      #define NF3D_API __declspec(dllimport) 
     #endif 
    #endif 
... 
#endif 

... 

extern NF3D_API CRITICAL_SECTION CriticalSection; 

class NF3D_API NF3DLock 
{ 
public: 
#pragma prefast(suppress:26166, "Thread safeness is enabeled.") 
    FORCEINLINE _Acquires_lock_(CriticalSection) NF3DLock(void) { EnterCriticalSection(&CriticalSection); } 
#pragma prefast(suppress:26165, "Thread safeness is enabeled.") 
    FORCEINLINE _Releases_lock_(CriticalSection) ~NF3DLock(void) { LeaveCriticalSection(&CriticalSection); } 
}; 

class NF3D_API STATE 
{ 
public: 
    ... 
    inline void SetMember(int val) { NF3DLock Lock; Elements.Member = val; } 
    inline int GetMember(void) { NF3DLock Lock; return Elements.Member; } 

private: 
    struct ELEMENTS 
    { 
     int Member; 
    } Elements; 
} 

FORCEINLINE NF3D_API STATE* NF3DGetEngineState(void); 

在State.cpp我初始化和刪除關鍵部分,但也:

CRITICAL_SECTION CriticalSection; 

... 

FORCEINLINE NF3D_API STATE* NF3DGetEngineState(void) 
{ 
    static STATE s_State; 
    return &s_State; 
} 

呼喚 'NF3DGetEngineState' 裏面的.dll文件不會引起問題和編譯運行非常好,但如果我用這個功能在發動機外部,裏面的應用程序,我得到的.exe文件鏈接錯誤:

2>Main.obj : error LNK2001: unresolved external symbol "struct _RTL_CRITICAL_SECTION NewFrontiers3D::CriticalSection" ([email protected]@@[email protected]@A) 

發動機包括在南稱爲'NewFrontiers3D'的空間。 當我將'extern NF3D_API CRITICAL_SECTION CriticalSection'聲明爲靜態時,這個錯誤使我更加感興趣,因爲它編譯得很好,但是在NF3DLock的構造函數中輸入臨界區時發生訪問衝突異常。另外,如果我刪除'EnterCriticalSection'和LeaveCriticalSection'鏈接器錯誤消失。我不知道發生了什麼,爲什麼發生這種情況,這就是爲什麼我會向任何可能幫助我的人解決這個問題。

回答

2

更新:

從行:

#define NF3D_API __declspec(dllexport) 

它看起來像你總是導出和導入從來沒有(這當標題從外部項目包括你應該做的)。

例如,使用定義NM3D_API_EXPORTS宏(如果我沒有記錯的話編譯代碼:-d選項

,然後,在頭以下列方式定義NM3D_API:

#ifdef NM3D_API_EXPORTS 
#define NM3D_API __declspec(dllexport) 
#else 
#define NM3D_API __declspec(dllimport) 
#endif 

原貼:

包括在一個非常愚蠢的方式工作,他們需要你,包括文件的全部內容,並將其粘貼在包含語句

這就是爲什麼當您試圖將此頭文件包含到不同的項目時,該項目不知道您以前的.dll中的聲明。由於它是在不同的文件中完成的,所以您的其他項目對此一無所知。

+0

你推薦我做什麼? –

+0

@VictorGabrielUngureanu那麼,如果我知道*爲什麼*你的代碼失敗了,並不意味着我知道你的問題的正確解決方案。但是,首先想到的第一個想法是在公共.dll頭文件中避免使用全局變量(或定義它們),而是編寫一個包裝函數,返回該變量(即編寫GetCriticalSection() CriticalSection變量)。 –

+0

此外,作爲一個側面問題,您是否可以在外部調用在.dll中定義的任何其他函數?在第二種看來,你似乎只是出口的代碼,但從來沒有進口(你應該做的情況下,當你的頭包括從外部項目) –

相關問題