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文件出现,否则该问题还是会出现。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在 SWIG使用智能指针(如 shared_ptr),你需要在接口文件中进行适当的声明和包装。以下是一个示例,展示了如何在 SWIG使用 shared_ptr。 首先,创建一个 C++ 类,例如 `Foo`,并在其头文件中添加相应的函数和成员变量: ```cpp // foo.h #include <iostream> #include <memory> class Foo { public: Foo(int value) : data(value) {} void printData() { std::cout << "Data: " << data << std::endl; } private: int data; }; ``` 然后,创建一个 SWIG 接口文件(.i 文件),用于声明和包装 C++ 类。在接口文件中,导入 `<memory>` 头文件,并使用 `%shared_ptr` 指令告诉 SWIG 如何处理 shared_ptr: ```swig // foo.i %module foo %{ #include "foo.h" %} %include <memory> %shared_ptr(Foo) %{ #include "foo.h" %} %include "foo.h" ``` 现在,你可以使用 SWIG 来生成包装器代码。运行以下命令: ```bash swig -c++ -python foo.i ``` 这将生成一个 C++ 封装器文件 `foo_wrap.cxx`,以及一个 Python 模块文件 `foo.py`。 接下来,你可以编译生成的封装器代码,并链接到 Python 解释器中。在这里,我们以 CMake 为例: ```cmake cmake_minimum_required(VERSION 3.12) project(foo) find_package(PythonLibs REQUIRED) include_directories(${PYTHON_INCLUDE_DIRS}) add_library(_foo SHARED foo_wrap.cxx) target_link_libraries(_foo ${PYTHON_LIBRARIES}) ``` 完成后,你将得到一个名为 `_foo.so` 的共享库文件,可以在 Python 中导入并使用 `Foo` 类的实例。这里是一个示例 Python 脚本: ```python import foo # 创建一个 Foo 对象的 shared_ptr foo_ptr = foo.Foo(42) # 使用 shared_ptr 调用成员函数 foo_ptr.printData() ``` 这样,你就可以在 SWIG使用智能指针(如 shared_ptr)来包装 C++ 类,并在 Python 中使用它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值