SWIG tcl:log4cpp 包装器的未定义符号错误

Posted

技术标签:

【中文标题】SWIG tcl:log4cpp 包装器的未定义符号错误【英文标题】:SWIG tcl : undefined symbol error for log4cpp wrapper 【发布时间】:2018-01-10 10:21:33 【问题描述】:

我是 log4cpp 和 swig 包装器的新手。我正在尝试使用 log4cpp 编写一个用于简单日志记录的接口。 我已经在我的 Ubuntu 机器上安装了 log4cpp 和 swig。

log4cpp.cpp:

#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Priority.hh"
#include "log4cpp.h"

void writeLog() 
        log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout);
        appender1->setLayout(new log4cpp::BasicLayout());

        log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "program.log");
        appender2->setLayout(new log4cpp::BasicLayout());

        log4cpp::Category& root = log4cpp::Category::getRoot();
        root.setPriority(log4cpp::Priority::WARN);
        root.addAppender(appender1);

        log4cpp::Category& sub1 = log4cpp::Category::getInstance(std::string("sub1"));
        sub1.addAppender(appender2);

        // use of functions for logging messages
        root.error("root error");
        root.info("root info");
        sub1.error("sub1 error");
        sub1.warn("sub1 warn");

        // printf-style for logging variables
        root.warn("%d + %d == %s ?", 1, 1, "two");

        // use of streams for logging messages
        root << log4cpp::Priority::ERROR << "Streamed root error";
        root << log4cpp::Priority::INFO << "Streamed root info";
        sub1 << log4cpp::Priority::ERROR << "Streamed sub1 error";
        sub1 << log4cpp::Priority::WARN << "Streamed sub1 warn";

        // or this way:
        root.errorStream() << "Another streamed error";

log4cpp.h:

void writeLog(void);

log4cpp.i:

%module log4cpp

%
#include "log4cpp.h"
%

%inline %
extern void writeLog(void);
%

我已完成以下步骤来生成 log4cpp.so 文件:

swig -tcl -c++ log4cpp.i
g++ -c -fPIC log4cpp.cpp log4cpp_wrap.cxx -I/usr/include/tcl8.5
g++ -shared log4cpp.o log4cpp_wrap.o -o log4cpp.so

它生成log4cpp_wrap.cxx, log4cpp.o, log4cpp_wrap.o and log4cpp.so 文件,没有任何警告和错误。

每当我在 tcl 中运行以下命令时。

load ./log4cpp.so

它会产生一个未定义的符号错误:

% load ./log4cpp.so
couldn't load file "./log4cpp.so": ./log4cpp.so: undefined symbol: _ZN7log4cpp8Appender29AppenderMapStorageInitializerD1Ev

如何消除此错误?

【问题讨论】:

该符号是log4cpp::Appender::AppenderMapStorageInitializer::~AppenderMapStorageInitializer() 的变形形式,即AppenderMapStorageInitializer 类的析构函数。不知道为什么类可见就看不到了…… 【参考方案1】:

您需要将 SWIG 共享库链接到 log4cxx,就像使用该库的任何其他 C++ 应用程序一样。所以当你打电话时

g++ -shared log4cpp.o log4cpp_wrap.o -o log4cpp.so

确实需要是这样的(但要适应真实的库和搜索路径)

g++ -shared log4cpp.o log4cpp_wrap.o -L/path/to/your/install/of/log4cxx -llog4cxx -o log4cpp.so 

【讨论】:

感谢您的回答。我已按照您的建议进行了更新:g++ -shared log4cpp.o log4cpp_wrap.o -L/usr/local/include/log4cpp -llog4cpp -o log4cpp.so 我发现以下错误: 发现如下错误:% load ./log4cpp.socannot find symbol "Log_Init" : path/log4cpp.so : undefined symbol : _Log_Init 看起来 log4cpp 需要你链接到其他东西才能使用它

以上是关于SWIG tcl:log4cpp 包装器的未定义符号错误的主要内容,如果未能解决你的问题,请参考以下文章

SWIG:numpy 包装器的意外结果?

如何使用 SWIG 在 C++ API 上生成 C 包装器? [复制]

Swig 中 C 指针的访问器函数

SWIG TCL:将类构造函数名称从 new_* 重命名为 create_*

SWIG 不接受指针参数的包装对象

将外部指针包装到 SWIG 数据结构中