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文件出現,否則該問題還是會出現。

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