SWIG打包C++为python接口

SWIG C++ ->python打包方法

 

1. swig安装

1.1. windows 环境下安装swig

Link: http://www.swig.org/download.html

  1. 直接下载swigwin
  2. 将下载后的swigwin.zip解压到本地任意目录
  3. 将解压后的目录打包,将swig.exe配置到PATH环境变量中
  4. 在cmd中测试输入swig,出现‘Must specify an input file. Use -help for available options.’表示安装成功

 

1.2. linux 环境下安装swig

Link: http://www.swig.org/download.html

LINK:    https://sourceforge.net/projects/pcre/files/pcre/8.41/pcre-8.41.tar.gz/download

  1. 直接下载swig 4.0.1
  2. 然后下载PCRE
  3. 安装pcre
  4. 安装swig
  5. 如果出现swig:error while loading shared libraries:libpcre.so.异常

输入#ln -s /usr/local/lib/libpcre.so.1 /lib

  1. 修改环境变量 vim /etc/profile  PATH=/usr/loacl/swig/bin:$PATH   $source /etc/profile

 

 

  1. Swig 使用方法

LINK :http://www.swig.org/Doc3.0/Introduction.html#Introduction_nn10

LINK:https://segmentfault.com/a/1190000013219667

 

Ps: 基础的打包方法上面两篇写的都非常详细了,看完上面两个就可以完成基本的C++程序python接口封装了,下面我要介绍的部分是针对python 和C++数据交互的部分。

 

    1. 传出int

C++ 传出int有两种方法:

  1. 直接在函数返回值返回
  2. 参数返回(传出参数)

在实际的工作中,第二种使用更多,这是因为,我们的函数返回值可能要做更多的事情,比如说,使用bool类型作为返回值,这样的话,我们就可以知道函数的运行情况,甚至在一些项目中,我们需要使用RUNCODE(函数运行状态)作为返回值,以及时知道函数的使用情况。

第一种方法,在swig打包中是不需要做额外操作的,我介绍的是第二种方法:

在 XXX.i文件中,我们需要添加下面的代码段:

%include "typemaps.i"

%apply int *OUTPUT { int *num };

注意点: int* num ,num这个字段和你实际C++算法中的参数要一致。这样在打包好python中,该API就变成了两个返回值(tuple形式),第一个返回值是你函数原始的返回自己,第二个返回值就是你的传出函数。

EX:   C++code   :void   getVcpBinNum(int* num);

      Python API : num = test_b.getVcpBinNum()

      其中getVcpBinNum函数的,参数部分就变成了返回值!,不需要再里面继续写参数。

    1. 传出short 一维数组

注意: 这里不仅仅表示的是short的一位数组,还有关于int 、 float 、double 、byte的一位数组。

在这个位置上,就是我们工作中最重要的一部,实现python C++数组交互,在很多时候python和C++交互上,一个是字符串(XML、JSON),一个是结构体二进制(struct、class)、一个就是数组。

一个熟练的C++程序员眼中,只要不是锯齿数组,一般情况下,不管是多少维的数组,都可以看作是一维数组,所以掌握一维数组就相当于掌握了全部的数组传入传出方法。

在swig的官方文档中,有关于carrays.i的使用方法,但是一旦使用了这个东西,就会陷入到一个大坑中,后面会有数不清的问题,因为carrays.i中使用 %array_class中生成的数组生成器,这个玩意生产的数组是没有边界检查的,结果就是你在python中使用数组生成器生成的数组,如果放在for 中去迭代直接可以跑到程序崩溃。

这里推荐另外一种方法,这个方法出现在了numpy的官方文档中(ps:对,swig的打包方法出现在numpy的官方文档中,真是日了狗!!!)

地址在:https://docs.scipy.org/doc/numpy/reference/swig.html

在这其中,详细讲解了各种维度的各种数组的传入传出方法。

这里我贴一个demo:

C++ API: short* getRefData(short*Data,int len,bool nc);

XXX.i  :

%{

#define SWIG_FILE_WITH_INIT

#include "XXX.h"

%}

 

%include "numpy.i"

 

%init %{

import_array();

%}

 

%apply (short* ARGOUT_ARRAY1, int DIM1) {(short* Data, int len)};

%include "XXX.h"

 

这里面 ARGOUT_ARRAY1 代表传出的一维数组,DIM1代表一维数组长度,所以这里即使我的API中len是没有在运算中使用的,我还是需要加上,不然就需要在.i中再包一层 %inline

 

Python使用方法:

ref_data=np.arange(14*width*width,dtype='short')

ref_data= test_b.getRefPPiData(np.shape(ref_data)[0],True)[1]#这里只需要维度!!

 

    1. 传出char*数组

 

所谓的char*数组,其实就是广义上的字符串,这里没有讲std::string,是因为,在业务中,很多时候有C/C++混编的情况,如果一个业务机器只有C环境,那么它就不能使用string的相关操作,所以在设计接口的时候,一般都会设计成char* ,或者const char* 这种比较兼容性好的接口。

下面是我的一个demo:

C++ API:  void getVcptType(char* vcp_type);

XX.i   :

%include "cstring.i"

%cstring_bounded_output(char *vcp_type, 32);

Python API:

vcp_type = test_b.getVcptType()

 

Char* 的传出使用的就是swig自带的一个cstring 配置文件。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ym影子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值