为C库生成Python SWIG绑定时的未定义符号

时间:2012-10-08 12:43:58

标签: python python-2.7 swig ld

我正在尝试与Python中的mdb库进行交互,使用SWIG根据mdb附带的头文件生成绑定。这是我第一次尝试这样做,并且在最终加载python中的共享库时,我遇到了一个未定义的符号。

这是我的界面定义文件:

$ cat pymdb.i
%module pymdb
%{
#include "mdbtools.h"
%}
%include "mdbtools.h"

生成C代码会抛出此警告:

$ swig -python -o pymdb.c -I/usr/include pymdb.i
/usr/include/mdbtools.h:187: Warning 451: Setting a const char * variable may leak memory.
/usr/include/mdbtools.h:188: Warning 451: Setting a const char * variable may leak memory.
/usr/include/mdbtools.h:189: Warning 451: Setting a const char * variable may leak memory.
/usr/include/mdbtools.h:190: Warning 451: Setting a const char * variable may leak memory.
/usr/include/mdbtools.h:191: Warning 451: Setting a const char * variable may leak memory.
/usr/include/mdbtools.h:192: Warning 451: Setting a const char * variable may leak memory.
/usr/include/mdbtools.h:193: Warning 451: Setting a const char * variable may leak memory.

编译C代码,一切看起来都很好:

$ gcc -c -fPIC -I/usr/include/python2.7 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include pymdb.c -o pymdb.o

将其链接到/usr/lib/x86_64-linux-gnu/libmdb.so.2.0.0文件(Debian multiarch):

$ ld -shared -lmdb pymdb.o -o _pymdb.so

这是我得到未定义的符号,在python中加载.so:

$ echo "import pymdb" |python
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pymdb.py", line 26, in <module>
    _pymdb = swig_import_helper()
  File "pymdb.py", line 22, in swig_import_helper
    _mod = imp.load_module('_pymdb', fp, pathname, description)
ImportError: ./_pymdb.so: undefined symbol: read_pg_if_16

mdbtools.h中有read_pg_if_16的声明:

extern guint16 read_pg_if_16(MdbHandle *mdb, int *cur_pos);

我可以在_pymdb.so文件表中看到未定义的符号:

$ objdump -T _pymdb.so |grep read_pg_if_16
0000000000000000      D  *UND*  0000000000000000 read_pg_if_16

但libmdb.so.2不提供此符号:

$ objdump -T /usr/lib/x86_64-linux-gnu/libmdb.so.2 |grep read_pg_if_16

我的界面文件中可能是错误吗?或者这可能是libmdb.so.2的问题,而不是暴露这个符号?我不是那么深入C和链接的东西,所以我在这一点上有点失去了如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

可能性是在头文件中声明了一个函数,但未在目标文件中定义。这在C中工作正常,其中在未引用的声明中没有问题,但是当swig包装声明时,它将创建一个引用,从而导致共享库无法加载。

相关问题