为静态库编译 SWIG Python 包装器?

Posted

技术标签:

【中文标题】为静态库编译 SWIG Python 包装器?【英文标题】:Compiling a SWIG Python wrapper for a static library? 【发布时间】:2011-01-05 20:19:38 【问题描述】:

这是一个菜鸟问题。我正在尝试学习如何使用 SWIG 为 C++ 库制作 python 接口。该库是专有的第 3 方库;它以头文件 (foo.h) 和静态存档 (libfoo.a) 的形式出现在我面前。

为了简化问题,我编写了一个我认为具有相同病态的示例。还是一样的错误信息。

/* foo.hpp */
class TC 
    public:
       TC();
       int i;
    private:
;

作为参考,这里是 foo.c。我只有真正的 3rd 方库的头文件和存档文件。

/*foo.cxx */
#include "foo.hpp"
TC::TC() 
    i = 0;

我通过输入 g++ -c foo.cxx && ar rcs libfoo.a foo.o 制作了这个库

我的 SWIG 接口文件如下:

/* foo.i */ 
%module foo
%
#include "foo.hpp"
%
%include "foo.hpp"

我通过键入生成 foo_wrap.cxx

swig -python -c++ foo.i

然后编译。

g++ -c -fPIC -I/usr/include/python2.6 foo_wrap.cxx 
g++ -shared -L. -lfoo -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -o _foo.so

编译成功,但是当我运行 Python 和 import foo 时,出现未定义符号错误。

>>> import foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
  File "foo.py", line 25, in <module>
    _foo = swig_import_helper() 
  File "foo.py", line 21, in swig_import_helper
    _mod = imp.load_module('_foo', fp, pathname, description)
ImportError: ./_foo.so: undefined symbol: _ZN2TCC1Ev

这里发生了什么?问题似乎是链接步骤没有找到构造函数 TC::TC 的定义。

注意:如果我将链接步骤更改为

g++ -shared -L. -lfoo -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -o _foo.so

然后一切正常。但是,对于我没有原始源代码的真正问题,这是一个选择吗?可以从 .a 中提取 .o 吗?大概可以手动完成,但不应该有一些自动化的方法吗?

【问题讨论】:

【参考方案1】:

我不确定您是否是这种情况,但总的来说,目标文件和静态库的顺序很重要。顺序定义了初始化的顺序。

您必须将最通用的对象和/或静态档案作为最后一个参数。具有最多依赖关系的对象/档案必须放在开头。

一个例子。目标文件 A.o 提供函数 A()。对象 B.o 使用函数 A()。你必须写ld -o libmy.so B.o A.o(最通用的文件A.o作为最后一个参数)。

您也可以通过objdump -x _foo.so检查该符号是否存在于文件中。

正确的调用是:g++ -shared -L. -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -lfoo -o _foo.so

不要与-lpython2.6混淆,它是一个动态库linkedruntime

【讨论】:

这条评论很有教育意义,似乎解决了我的问题。谢谢!不幸的是,我没有足够的声望来投票。 通过接受你的回答,我得到了足够的代表给你投票!

以上是关于为静态库编译 SWIG Python 包装器?的主要内容,如果未能解决你的问题,请参考以下文章

无法为 c++ python 扩展编译 swig 生成的包装器

在 Windows 中为 python 编译 SWIG 包装器

使用 SWIG 的 C++ 的 Python 包装器

将 C 库与 Haskell 库静态链接

Swig:包装全局静态常量时出现语法错误

在 Windows 中编译 SWIG python 包装器时,MinGW g++ 找不到 numpy\arrayobject.h