使用 SWIG 的 C++ 的 Python 包装器

Posted

技术标签:

【中文标题】使用 SWIG 的 C++ 的 Python 包装器【英文标题】:Python wrapper for C++ using SWIG 【发布时间】:2017-11-19 13:22:02 【问题描述】:

我将使用 SWIG 为一些 c++ 代码编写一个 python 包装器。主类是 Cryptographer,它使用两个 static 库,即 libgmp.alibgmpxx.a。所以我的代码是这样的(为简单起见,删除了一些实现代码):

example.h:

/* example.h */
#include <string.h>
#include <string>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include "gmp.h"
#include "gmpxx.h"

using namespace std;

class Cryptographer 
    private:
        mpz_class num;
    public:
        Cryptographer();
        virtual ~Cryptographer();
;

example.cpp:

/* example.cpp */
#include "example.h"

Cryptographer::Cryptographer() 
    num = 12;


Cryptographer::~Cryptographer() 

针对上面的两个文件,创建了一个 SWIG 接口:

example.i:

%module example
% 
    #define SWIG_FILE_WITH_INIT
    #include "example.h"
%
%include "example.h"

然后我运行这些命令:(取自here)

swig -c++ -python example.i // creates "example_wrap.cxx"

gcc -c -fPIC example_wrap.cxx -I/usr/include/python2.7 // outputs "example_wrap.o"

gcc -c -fPIC example.cpp -I/usr/include/python2.7 // creates "example.o"

g++ -shared example_wrap.o example.o -o example.so // creates "example.so"

然后我尝试在 python2.7 中导入example 模块,但不幸的是它不起作用:

Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ImportError: ./example.so: undefined symbol: __gmpz_set_si

我猜是那些 libgmplibgmpxx 库在链接过程中没有正确链接,但我不知道如何修复它。 p>

顺便说一句,this link 可以访问所有需要的文件。

【问题讨论】:

能提供gcc版本吗? @p-a-o-l-o 给你:gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 【参考方案1】:

这在 gcc 6.3.0 中运行良好:

g++ -shared -o _example.so example_wrap.o example.o libgmp.a libgmpxx.a

不过,您可能需要提供 .a 文件的完整路径。

而这些库需要位置无关的代码(又名 -fPIC)编译。

重建库: 1) 下载这个:https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2 2) 将文件提取到选择的目录中。 3)从那个目录,运行这个命令:

./configure --with-pic=yes --enable-cxx

如果一切顺利,您将拥有Makefile。 因此,请立即致电makemake install。完毕。

【讨论】:

您可以在python中导入example模块而不会出现任何错误?我测试了命令,但对我来说它给出了错误:/usr/bin/ld: libgmp.a(memory.o): relocation R_X86_64_32 against .rodata.str1.8' can not be used when making a shared object; recompile with -fPIC libgmp.a: error adding symbols: Bad value collect2: error: ld returned 1 exit status 实际上它给出了“ImportError:动态模块没有定义初始化函数(initexample)”,但我摆脱了它,将库重建为_example.so。链接器问题已经解决,我更新了答案以澄清您的重定位问题。 这一次你可以在python中导入模块吗?请将用于重建这两个库的命令添加到帖子中,以便我可以按照您的操作进行操作,非常感谢。 已更新。祝你好运。 哇,它现在运行完美。我知道我会遇到错误:“ImportError:动态模块没有定义初始化函数(initexample)”但是你提前解决了这个问题,非常感谢。

以上是关于使用 SWIG 的 C++ 的 Python 包装器的主要内容,如果未能解决你的问题,请参考以下文章

使用 SWIG 为 Python 包装 C++。 “向量”未声明

使用 SWIG 围绕 C++ 的 Python 包装器。参数类型无法识别

使用 SWIG 包装对象从 C++ 调用 Python 函数的最简洁方法是啥

使用python包装的c ++ SWIG模拟输入

SWIG C++ Python:通过引用或指针包装 int

如何使用 SWIG 包装一个在 python 中接收函数指针的 c++ 函数