使用 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.a 和 libgmpxx.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
我猜是那些 libgmp 和 libgmpxx 库在链接过程中没有正确链接,但我不知道如何修复它。 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
。
因此,请立即致电make
和make 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 包装器。参数类型无法识别