我正在使用 log4cplus(从当前的 git master 编译),但链接器收到未定义的引用错误。但是,这些错误仅发生在某些类中。
一般来说,每个类都有以下形式:
标头 (.h)
// ...
#include <log4cplus/loggingmacros.h>
// ...
// namespace(s)
class Example
{
public:
// ...
private:
// ...
static const log4cplus::Logger logger;
};
源 (.cpp)
// includes
// namespace(s)
// implementations
const log4cplus::Logger Example::logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("Example"));
用法
记录器在类中使用,如下所示:
LOG4CPLUS_WARN(logger, "Ha, ha – whatever you try I wont work!");
在编译工作时,链接器会引发未定义的引用错误
log4cplus::Logger::getInstance(std::string const&)
和
log4cplus::detail::macro_forced_log(log4cplus::Logger const&, int, std::string const&, char const*, int, char const*)
对于某些课程。我已经从工作班复制了记录器部分:相同的结果。
用类成员替换静态记录器也不起作用——getInstance()
没有找到。
这个问题的解决方法是使用 root-logger 代替;这将编译/链接(即使getRoot()
是同一类的一部分!?):
const log4cplus::Logger Example::logger = log4cplus::Logger::getRoot();
但是还有未定义的引用错误
log4cplus::detail::macro_forced_log(...)
为了确保没有错字,我使用这些宏进行声明/定义:
#define LOG_DECL(name) static const log4cplus::Logger logger
#define LOG_DEF(name) const log4cplus::Logger name::logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT(#name))
同样的结果,那些以前有效的也有效,而那些不……没有。
更多信息:
- Log4cplus 使用 -llog4cplusSU 链接(也使用 log4cplusS 进行了测试)并从它的 git master 编译
- GCC 4.9 – 使用 C++11
- 用于构建项目的 Eclipse CDT
- Log4cplus 在 main 中初始化
- 所有类都使用相同的编译器和标志编译
- 完全清理和构建项目
- 所有文件都以相同的方式编译/链接
- const / not const 没有效果
结果nm <NAME>.o | grep -i log4cplus
:
工作对象
U _ZN9log4cplus6detail16macro_forced_logERKNS_6LoggerEiRKSbIwSt11char_traitsIwESaIwEEPKciSB_
0000000000000000 W _ZN9log4cplus6detail17macros_get_loggerERKNS_6LoggerE
U _ZN9log4cplus6detail18get_macro_body_ossEv
U _ZN9log4cplus6Logger11getInstanceERKSbIwSt11char_traitsIwESaIwEE
U _ZN9log4cplus6LoggerC1ERKS0_
U _ZN9log4cplus6LoggerD1Ev
00000000000002c8 r _ZN9log4cplusL13ALL_LOG_LEVELE
00000000000002ac r _ZN9log4cplusL13OFF_LOG_LEVELE
00000000000002bc r _ZN9log4cplusL14INFO_LOG_LEVELE
00000000000002b8 r _ZN9log4cplusL14WARN_LOG_LEVELE
00000000000002c0 r _ZN9log4cplusL15DEBUG_LOG_LEVELE
00000000000002b4 r _ZN9log4cplusL15ERROR_LOG_LEVELE
00000000000002b0 r _ZN9log4cplusL15FATAL_LOG_LEVELE
00000000000002c4 r _ZN9log4cplusL15TRACE_LOG_LEVELE
00000000000002cc r _ZN9log4cplusL17NOT_SET_LOG_LEVELE
U _ZNK9log4cplus6Logger12isEnabledForEi
带有未定义的引用:
U _ZN9log4cplus6detail16macro_forced_logERKNS_6LoggerEiRKSsPKciS7_
0000000000000000 W _ZN9log4cplus6detail17macros_get_loggerERKNS_6LoggerE
U _ZN9log4cplus6detail18get_macro_body_ossEv
U _ZN9log4cplus6Logger11getInstanceERKSs
U _ZN9log4cplus6LoggerC1ERKS0_
U _ZN9log4cplus6LoggerD1Ev
00000000000001ec r _ZN9log4cplusL13ALL_LOG_LEVELE
00000000000001d0 r _ZN9log4cplusL13OFF_LOG_LEVELE
00000000000001e0 r _ZN9log4cplusL14INFO_LOG_LEVELE
00000000000001dc r _ZN9log4cplusL14WARN_LOG_LEVELE
00000000000001e4 r _ZN9log4cplusL15DEBUG_LOG_LEVELE
00000000000001d8 r _ZN9log4cplusL15ERROR_LOG_LEVELE
00000000000001d4 r _ZN9log4cplusL15FATAL_LOG_LEVELE
00000000000001e8 r _ZN9log4cplusL15TRACE_LOG_LEVELE
00000000000001f0 r _ZN9log4cplusL17NOT_SET_LOG_LEVELE
U _ZNK9log4cplus6Logger12isEnabledForEi
失败的最小类
//////////////////////// Header ////////////////////////
namespace so {
namespace example {
class FailingExample
{
public:
FailingExample(other_ns::Config* config, other_ns::Command* cmd);
bool updateData(uint8_t* dataPtr, uint32_t dataSize);
virtual ~FailingExample();
private:
static const log4cplus::Logger logger;
};
}}
//////////////////////// Source ////////////////////////
namespace so {
namespace example {
FailingExample::FailingExample(other_ns::Config* config, other_ns::Command* cmd)
{
}
bool FailingExample::updateData(uint8_t* dataPtr, uint32_t dataSize)
{
return true;
}
FailingExample::~FailingExample()
{
}
// Undefined reference to getInstance() here
const log4cplus::Logger FailingExample::logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("FailingExample"));
}}