我正在努力使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?您可能最终会遇到意想不到的副作用。因此,以这种方式进行操作有助于防止出现此类问题。

希望能有所帮助。

10-05 22:40