swig使用介绍

swig是Simplified Wrapper and Interface Generator的简称,它是一个能将C和C++的程序与其他各种高级语言诸如Perl,Python,Ruby和Tcl进行连结的开发工具。

swig的官方中文网站:http://www.swig.org/translations/chinese

什么是typemap

tymemap are an advanced customization feature that provide direct access to SWIG's low-level code generator. Not only that, they are an integral part of the SWIG C++ type system (a non-trival topic of its own). Typemaps are generally not a required part of using SWIG. 

typemap是一个先进的定制化功能,可以提供直接访问SWIG的底层的代码生成器。除了这些,它也是SWIG C++类型系统完整的一部分。

typemap告诉SWIG如何去匹配Python对象和C/C++的函数参数,反之亦然。假设,我想实现一个类似与Python的join()函数,该函数接受一个列表,然后返回将列表中所有元素拼接而成的字符串,如下所示:

>>> import rgb2yuv
>>> print rgb2yuv.list2str([83, 120])
Sx

那对应的C++函数则为如下所示:

std::string list2str(unsigned char *yuyv_arr, int k)

相应的.i文件需要含有如下的关键语句

%apply (unsigned char *IN_ARRAY1, int DIM1) {(unsigned char *yuyv_arr, int k)};

其中需要注意的有以下几点:

1、apply后面跟的{(unsigned char *yuyv_arr, int k)}需要与.h文件中的函数声明保持完全一致,即便形参也需要保持一致;

2、IN_ARRAY1代表是一维数组,如果函数有两个数组参数,则为(unsigned char *IN_ARRAY1, unsigned char *IN_ARRAY1),而不能为(unsigned char *IN_ARRAY1, UNSIGNED char *IN_ARRAY2)。因为IN_ARRAY1和IN_ARRAY2分别代表一维数组和二维数组;

3、C++的实现需要将数组大小作为参数传进去,否则无法知道数组的大小。但是在Python调用时只需要传入第一个列表参数即可,如果传入第一个数组大小的参数则会报错。

实例1:想要实现rgb转yuv的一个函数,他的输入为rgb格式的数组,输出为yuv格式的数组。

rgb2yuv.c为


 void rgb2yuyv(unsigned char *rgb_arr, int m, unsigned char *yuv_arr, int n)
 {
     unsigned char y0 = 0;
     unsigned char y1 = 0;
     unsigned char u = 0;
     unsigned char v = 0;
 
     unsigned char r1 = 0;
     unsigned char g1 = 0;
     unsigned char b1 = 0;
     unsigned char r2 = 0;
     unsigned char g2 = 0;
     unsigned char b2 = 0;
 
     int j = 0;
     for(int i = 0; i < m; i += 6)
     {
         r1 = rgb_arr[i];
         g1 = rgb_arr[i+1];
         b1 = rgb_arr[i+2];
 
         get_yuv(r1, g1, b1, &y0, &u, &v);
 
         r2 = rgb_arr[i+3];
         g2 = rgb_arr[i+4];
         b2 = rgb_arr[i+5];
 
         get_yuv(r2, g2, b2, &y1, &u, &v);
         yuv_arr[j] = y0;
         yuv_arr[j+1] = u;
         yuv_arr[j+2] = y1;
         yuv_arr[j+3] = v;
         j += 4;
     }
 }

rgb2yuv.i为

 %module rgb2yuv
 
 %{
     #define SWIG_FILE_WITH_INIT
     #include "rgb2yuv.h"
 %}
 
 %include "numpy.i"
 
 %init %{
     import_array();
 %}
 
 %apply (double *IN_ARRAY1, int DIM1) {(double *vec, int m)};
 %apply (double *ARGOUT_ARRAY1, int DIM1) {(double *vec2, int n)};
 
 %include "rgb2yuv.h"

遇到的问题

1、<Swig Object of type 'uint32_t *' at 0x7f368eacbcf0>swig/python detected a memory leak of type 'uint32_t *', no destructor found.

解决方法:增加%include "stdint.i" 在.i文件的头部

2、TypeError: in method 'FpgaApi_get_register_value', argument 2 of type 'std::string &'

解决方法:将get_register_value()中std::string &改为const std::string &

3、TypeError: in method 'new_FpgaApi', argument 1 of type 'std::string const &'

解决方法:增加%include <std_string.i>在.i文件的头部。注意,这一行内容一定要先于对应的.h文件出现,否则该问题还是会出现。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章