This is a noob question. I'm trying to learn how to use SWIG to make a python interface for a C++ library. The library is a proprietary 3rd party library; it comes to me in the form of a header file (foo.h) and a static archive (libfoo.a).
To simplify matters, I've cooked up an example which I think has the same pathology. Same error messages anyways.
/* foo.hpp */
class TC {
public:
TC();
int i;
private:
};
For reference, here's foo.c. I only have the header and archive files for the real 3rd party library.
/*foo.cxx */
#include "foo.hpp"
TC::TC() {
i = 0;
}
I made this library by typing g++ -c foo.cxx && ar rcs libfoo.a foo.o
My SWIG interface file is as follows:
/* foo.i */
%module foo
%{
#include "foo.hpp"
%}
%include "foo.hpp"
I generate foo_wrap.cxx by typing
swig -python -c++ foo.i
and then compile.
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
The compilation succeeds, but when I run Python and import foo
, I get an undefined symbol error.
>>> 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
What's going on here? The problem seems to be that the linking step isn't finding the definition of the constructor TC::TC.
Note: If I alter the linking step to
g++ -shared -L. -lfoo -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -o _foo.so
then everything works. But is this an option for my real problem, where I don't have the raw source code? Can one extract a .o from a .a? Presumably one can do this by hand, but shouldn't there be some automated way of doing it?