2011-01-05 53 views
1

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

为了简化问题,我制作了一个我认为具有相同病理学的例子。反正同样的错误信息。

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

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

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

我通过键入使这个图书馆g++ -c foo.cxx && ar rcs libfoo.a foo.o

我痛饮接口文件如下:

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

我通过键入

swig -python -c++ foo.i 

,然后编译生成foo_wrap.cxx 。

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吗?大概人们可以手动做到这一点,但不应该有一些自动化的方式来做到这一点?

回答

6

我不太确定这是否适合您,但一般来说目标文件和静态库的顺序很重要。该顺序定义了初始化的顺序。

您必须将最常用的对象和/或静态存档作为最后一个参数。最依赖的对象/档案必须放在开头。

一个例子。目标文件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混淆,它在运行时链接一个动态库

+0

此评论很有教育意义,似乎解决了我的问题。谢谢!不幸的是,我没有足够的声望来赞扬。 – user1504 2011-01-05 20:53:51

+0

通过接受你的回答,我得到了足够的代表给你一票! – user1504 2011-01-05 21:07:47