2015-10-16 91 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中定义的任何其他函数?在第二种看来,你似乎只是出口的代码,但从来没有进口(你应该做的情况下,当你的头包括从外部项目) –

相关问题