为静态库编译 SWIG Python 包装器?

发布于 2024-10-10 05:43:07 字数 1530 浏览 8 评论 0原文

这是一个菜鸟问题。我正在尝试学习如何使用 SWIG 为 C++ 库制作 python 接口。该库是专有的第三方库;它以头文件(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

那么一切都会正常。但这是我没有原始源代码的真正问题的选择吗?可以从 .a 中提取 .o 吗?想必人们可以手动完成此操作,但不应该有某种自动化的方法来完成此操作吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

可爱暴击 2024-10-17 05:43:07

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

您必须将最通用的对象和/或静态档案作为最后一个参数。具有最多依赖性的对象/档案必须放置在开头。

一个例子。目标文件 Ao 提供函数 A()。对象 Bo 使用函数 A()。你必须写ld -o libmy.so Bo Ao(最通用的文件Ao作为最后一个参数)。

您还可以使用 objdump -x _foo.so 检查该符号是否存在于文件中。

正确的调用是:g++ -shared -L。 -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -lfoo -o _foo.so

不要与 -lpython2.6 混淆,它是一个动态库链接 运行时

I'm not really sure if it's the case for you but in general the order of object files and static libraries matters. The order defines the order of initialisation.

You have to put the most general objects and/or static archives as last parameters. The objects/archives with the most dependencies have to be placed at the beginning.

An example. The object file A.o offer the fucntion A(). The object B.o uses the function A(). You have to write ld -o libmy.so B.o A.o (the most general file A.o as last parameter).

You can also check with objdump -x _foo.so if the symbol exists in the file.

The right call would be: g++ -shared -L. -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -lfoo -o _foo.so

Do not be confused with -lpython2.6, it's a dynamic library linked at runtime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文