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

use*_*504 1 c++ python swig static-libraries undefined-symbol

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

为了简化问题,我已经制作了一个我认为具有相同病理的例子.反正相同的错误消息.

/* foo.hpp */
class TC {
    public:
       TC();
       int i;
    private:
};
Run Code Online (Sandbox Code Playgroud)

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

/*foo.cxx */
#include "foo.hpp"
TC::TC() {
    i = 0;
}
Run Code Online (Sandbox Code Playgroud)

我通过打字创建了这个库 g++ -c foo.cxx && ar rcs libfoo.a foo.o

我的SWIG接口文件如下:

/* foo.i */ 
%module foo
%{
#include "foo.hpp"
%}
%include "foo.hpp"
Run Code Online (Sandbox Code Playgroud)

我输入生成foo_wrap.cxx

swig -python -c++ foo.i
Run Code Online (Sandbox Code Playgroud)

然后编译.

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
Run Code Online (Sandbox Code Playgroud)

编译成功,但是当我运行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
Run Code Online (Sandbox Code Playgroud)

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

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

g++ -shared -L. -lfoo -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -o _foo.so
Run Code Online (Sandbox Code Playgroud)

一切正常.但这是我真正的问题的一个选项,我没有原始的源代码?可以从.a中提取.o吗?据推测,人们可以手工完成这项工作,但是不应该有一些自动化的方法吗?

Rap*_*sek 6

我不确定你是否属于这种情况,但一般情况下,目标文件和静态库的顺序很重要.该订单定义了初始化的顺序.

您必须将最常用的对象和/或静态存档作为最后的参数.具有最多依赖性的对象/存档必须放在开头.

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

您还可以检查objdump -x _foo.so文件中是否存在符号.

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

不要与-lpython2.6混淆,它是在运行时链接的动态库.