1

I'm trying to interface with the mdb library in Python, using SWIG to generate bindings based on the header file shipped with mdb. It's my first attempt to do so and I'm stuck with an undefined symbol when finally loading the shared library in python.

Here's my interface definition file:

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

Generating the C code throws this warnings:

$ 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.

Compiling the C code, everything looks fine:

$ 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

Linking it to the /usr/lib/x86_64-linux-gnu/libmdb.so.2.0.0 file (Debian multiarch):

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

And this is where I get the undefined symbol, loading the .so in python:

$ 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

There is a declaration for read_pg_if_16 in mdbtools.h:

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

I can see the undefined symbol in the _pymdb.so files table:

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

But libmdb.so.2 does not offer this symbol:

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

Could it be an error in my interface file? Or is this possibly a problem with the libmdb.so.2, not exposing this symbol? I'm not that deep into C and linking stuff, so I'm a bit lost at this point on how to proceed to nail down this problem.

Fladi
  • 177
  • 1
  • 11
  • Quick guess: does changing the order of the arguments when linking fix things? See http://stackoverflow.com/questions/8140494/why-am-i-getting-a-gcc-undefined-reference-error-trying-to-create-shared-objec/8140599#8140599 if it does. – Flexo Oct 09 '12 at 07:12

1 Answers1

1

On possibility is that a function is declared in the header files, but not defined in the object files. This works fine in C where having in unreferenced declaration is not a problem, but when swig wraps the declaration, it will create a reference, thus causing the shared library to not load.

Andrew Prock
  • 6,900
  • 6
  • 40
  • 60