我目前正在开发一个由两个部分组成的游戏:引擎在.dll中,实际的游戏代码是.exe的一部分。除了其他头文件之外,引擎还包含一个管理所有组件的引擎,这些组件从Win32特定的对象和指针到D3D11。这些组件包含在一个类中,该类允许通过返回引用的函数全局访问这些组件。此外,对于它管理的每个项,有两个函数允许设置或返回组件。我还使用关键部分添加了线程保护。所以,在国家,我有:
#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" (?CriticalSection@NewFrontiers3D@@3U_RTL_CRITICAL_SECTION@@A)引擎包含在一个名为“NewFrontiers3D”的命名空间中。当我将'extern NF3D_API CRITICAL_SECTION CriticalSection‘声明为静态时,这个错误引起了我更大的兴趣,因为它编译得很好,但在进入NF3DLock构造函数的关键部分时却出现了访问冲突异常。另外,如果删除“EnterCriticalSection”和“LeaveCriticalSection”,链接器错误就会消失。我不知道发生了什么,为什么会发生,这就是为什么我要向任何有能力帮助我的人提出这个问题。
发布于 2015-10-16 18:39:34
更新:
从线上说:
#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原文:
以一种非常愚蠢的方式包括了他的工作。它们获取包含的文件的全部内容,并将其粘贴到include语句上。
这就是为什么当您试图将此头包含到另一个项目时,该项目不知道您在前一个.dll中的声明。因为它是在另一个文件中完成的,因此您的其他项目对此一无所知。
https://stackoverflow.com/questions/33177303
复制相似问题