我正在努力使rLog在Windows下以DLL的形式生成,并且出现与rlog命名空间中某些全局符号有关的 undefined symbol 错误。特别是在RLogChannel.cpp中的这些:
namespace rlog {
...
RLogChannel *_RLDebugChannel = GetGlobalChannel( "debug", Log_Debug );
RLogChannel *_RLInfoChannel = GetGlobalChannel( "info", Log_Info );
RLogChannel *_RLWarningChannel = GetGlobalChannel( "warning", Log_Warning );
RLogChannel *_RLErrorChannel = GetGlobalChannel( "error", Log_Error );
...
};
我认为问题是1)它们没有被导出,2)它们没有在头文件中声明,以便其他东西可以访问它们。因此,我向它们添加了__declspec(dllexport)(通过RLOG_DECL宏),并在标题中放入:
namespace rlog {
...
RLOG_DECL extern RLogChannel *_RLDebugChannel;
RLOG_DECL extern RLogChannel *_RLInfoChannel;
RLOG_DECL extern RLogChannel *_RLWarningChannel;
RLOG_DECL extern RLogChannel *_RLErrorChannel;
...
};
但是,无论我如何在RLogChannel.cpp中声明变量,尽管我在 header 中将其替换了,但还是得到了重新定义错误……什么是正确的方法?似乎应该很简单,但是我无法完全解决。
编辑:错误消息
Error 12 error C2086: 'rlog::RLogChannel *rlog::_RLDebugChannel' : redefinition rlog-1.4\rlog\RLogChannel.cpp 45 rlog
(所有4个符号相同)
编辑:我不知道发生了什么,代码之前完全相同,但现在可以编译(感觉像MSVC怪异...),不幸的是,链接到我的库时,符号仍然显示为未解析
最佳答案
解决此问题的一种方法是在一个位置和标题中一次定义它们。
但是,如果仅将所有定义转移到标题,则会遇到多定义问题。
一个解决方案就是这个。假设文件名为rlog.c和rlog.h
--- (rlog.h) ---
#ifdef RLOG_DEFINES
#define EXTERN
#else
#define EXTERN extern
#endif
namespace rlog {
...
RLOG_DECL EXTERN RLogChannel *_RLDebugChannel;
RLOG_DECL EXTERN RLogChannel *_RLInfoChannel;
RLOG_DECL EXTERN RLogChannel *_RLWarningChannel;
RLOG_DECL EXTERN RLogChannel *_RLErrorChannel;
...
};
--- (rlog.c) ---
#define RLOG_DEFINES
#include "rlog.h"
...
--- (other .c files) ---
#include "rlog.h"
此解决方案的优点在于,因为定义仅在项目中定义一次,因此您永远不会使它们彼此不同步,并且只需要在一个位置进行更改即可。想像一下,如果您将变量定义为long,但在extern定义中将其声明为short?您可能最终会遇到意想不到的副作用。因此,以这种方式进行操作有助于防止出现此类问题。
希望能有所帮助。