Компилирование оболочки SWIG Python для статической библиотеки? - PullRequest
1 голос
/ 05 января 2011

Это нубский вопрос. Я пытаюсь узнать, как использовать SWIG для создания интерфейса Python для библиотеки C ++. Библиотека является проприетарной сторонней библиотекой; он приходит ко мне в виде заголовочного файла (foo.h) и статического архива (libfoo.a).

Чтобы упростить дело, я подготовил пример, который, я думаю, имеет ту же патологию. В любом случае, одни и те же сообщения об ошибках.

/* 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

Мой файл интерфейса SWIG выглядит следующим образом:

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

Я генерирую foo_wrap.cxx, набрав

swig -python -c++ foo.i

, а затем скомпилировать.

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

тогда все работает. Но это вариант для моей реальной проблемы, где у меня нет исходного кода? Можно ли извлечь .o из .a? Предположительно можно сделать это вручную, но разве не должен быть какой-то автоматизированный способ сделать это?

1 Ответ

6 голосов
/ 05 января 2011

Я не совсем уверен, так ли это для вас, но в целом порядок объектных файлов и статических библиотек имеет значение.Порядок определяет порядок инициализации.

Вы должны поместить самые общие объекты и / или статические архивы в качестве последних параметров.Объекты / архивы с наибольшим количеством зависимостей должны быть размещены в начале.

Пример.Объектный файл 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, это динамическая библиотека связанная в время выполнения .

...