SWIG 打包C++数组供python调用 tcy

1.1.carrays.i        
用途:   
    该模块定义将普通C指针包装为数组的宏;不提供任何安全性;
    仅提供用于创建,销毁和修改原始C数组数据内容的功能     
1.2.%array_functions(type, name)  
    用途:创建四个函数,供你创建销毁辅值及读数组元素
    函数:
        type *new_name(int nelements)  //创建新动态数组分配内存
        type *delete_name(type *ary)  //销毁数组
        type name_getitem(type *ary, int index)  //读数组元素
        void name_setitem(type *ary, int index, type value)  //设置设置元素
            
    说明:type可是任何类型;name不应该与接口文件中有重名

    示例:        
    void print_array(double x[6]) {  
        int i;  
        for (i = 0; i < 6; i++) { printf("[%d] = %g\n", i, x[i]);  }  
    }  

    包装:        
          %module example  
            
          %include "carrays.i"  
          %array_functions(double, doubleArray);  
            
          void print_array(double x[10]);  
          
    python测试:         
        a = new_doubleArray(10)               # Create an array  
        for i in range(0, 10):  
          doubleArray_setitem(a, i, 2 * i)     # Set a value  
          
        print_array(a)                                  # Pass to C  
        delete_doubleArray(a)                    # Destroy array  
1.3.%array_class(type, name)  
        
用途:将指针包装为类;在基于类接口内包装*类型指针;常与代理类结合使用    
注意:类型限制为简单类型如int或float   
结构:
    struct name {  
        name(int nelements);                      // Create an array  
        ~name();                                           // Delete array  
        type getitem(int index);                    // Return item  
        void setitem(int index, type value);  // Set item  
        type *cast();                                      // Cast to original type  
        static name *frompointer(type *);     // Create class wrapper from  existing pointer  
    };  

实例:
    %module example  
    %include "carrays.i"  
    %array_class(double, doubleArray);  

    void print_array(double x[10]);  
    
    python操作:        

    import example  
    
    c = example.doubleArray(10)  # Create double[10]  
    for i in range(0, 10):  
      c[i] = 2 * i                               # Assign values  
    example.print_array(c)             # Pass to C  

1.4.注意:
    %array_functions,%array_class宏不会将C数组封装在特殊数据结构或代理中
    没有边界检查或任何形式安全性。如需要应该考虑使用特殊数组对象而不是裸指针

    %array_functions,%array_class不应与char或char *类型一起使用
    SWIG对这些类型默认作为字符串处理   
2.实例:

实例1:数组-自定义辅助函数
#pragma once
//1.1.example.h

void add(float *rst_arr, const float *arr, int rst_size, int size);

//1.2.Example.cpp
#include "Example.h"

void add(float *rst_arr, const float *arr, int rst_size, int size)
{
 float n = 0;
 
 for (int i = 0;i < rst_size; i++)
 {
  if (i < size)
   rst_arr[i] = arr[i] + 100;
  else
   rst_arr[i] = n + 100;

  n += 1;
 }
}

//1.3.1.SWIG接口文件Example.i
//自定义数组辅助函数

%module Example//定义模块名

%{
#include "Example.h"
%}

#include "Example.h"
using namespace std;

%inline%{

static float *new_floatArray(size_t nelements) { 
    return (new float[nelements]());
}

static void delete_floatArray(float *ary){
 delete[] ary;
}

static float floatArray_getitem(float *ary, size_t index) {
    return ary[index];
  }
static void floatArray_setitem(float *ary, size_t index, float value) {
    ary[index] = value;
}

%}

void add(float *rst_arr,const float *arr, int rst_size, int size);

//1.3.2.SWIG接口文件Example.i
//用carray.i

%module Example//定义模块名
%include "carrays.i"
%array_functions(float, floatArray);

%{
#include "Example.h"
%}

#include "Example.h"
using namespace std;

%}

void add(float *rst_arr,const float *arr, int rst_size, int size);

//1.3.3.SWIG接口文件Example.i
//自定义数组辅助类(推荐)自动释放指针

%module Example//定义模块名

%{
#include "Example.h"
%}

#include "Example.h"
using namespace std;

%inline%{

class FloatArrClass
{
private:
 size_t size;
 float *p_float;

public:
 size_t getSize(){return size;}
 float *getFloatPointer(){return p_float;}

 float *new_floatArray(size_t nelements) {
  return (new float[nelements]());
 }

 void delete_floatArray(float *ary) {
  delete[] ary;
 }

 float floatArray_getitem(float *ary, size_t index) {
  return ary[index];
 }
 void floatArray_setitem(float *ary, size_t index, float value) {
  ary[index] = value;
 }
    
    void floatArray_setitem(float *ary, size_t index, float value) {
  ary[index] = value;
 }//swig不支持设置arr[]下标重载
    
 FloatArrClass() { size = 0; }
 FloatArrClass(size_t n) { size = n; p_float = new_floatArray(n); }
 FloatArrClass(const FloatArrClass &o) { size = o.size; p_float = o.p_float; }
 ~FloatArrClass() {
  if (p_float != NULL) { delete_floatArray(p_float); p_float = NULL; }
 }
};  

%}

void add(float *rst_arr,const float *arr, int rst_size, int size);

//1.4.python测试程序:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

# from Swig.Camera import add,HalconClass
import numpy as np
import sys,os,shutil

def copyfile(b=True):
    if b==False:return
    pypath=r'C:\Users\Administrator\Desktop\Fastener\Swig'
    cpath=r'C:\Users\Administrator\Desktop\ProjectSwigWin\x64\Release'
    filename=r'Example'
    cfile_py=cpath+'\\'+filename+'.py'
    cfile_pyd=cpath+r'\ProjectSwigWin.pyd'

    pyfile_py=pypath+'\\'+filename+'.py'
    pyfile_pyd=pypath+r'\_'+filename+'.pyd'

    print(cfile_py)
    if os.path.isfile(cfile_py):
        shutil.copyfile(cfile_py,pyfile_py)
    else:
        print('not camera.py',cfile_py)
        return

    if os.path.isfile(cfile_pyd):
        shutil.copyfile(cfile_pyd,pyfile_pyd)
    else:
        print('not camera.pyd')
        return

copyfile()
from Swig import Example  as obj

#数组测试:
def test_Add_C_PulsPulse(obj,obj1,obj2,rst_arr,arr,n=6):
    obj1=obj1 if obj1 else obj
    obj2 = obj2 if obj2 else obj
    for i in range(n):           #初始化数组
        obj1.floatArray_setitem(rst_arr, i, 0)
        obj2.floatArray_setitem(arr, i, i)

    obj.add(rst_arr,arr, n, n)#rst_arr=arr+100

    print('test arr:')
    for i in range(6):             #显示数组元素
        print("[%6.2f %6.2f]" % (obj.floatArray_getitem(rst_arr, i), obj.floatArray_getitem(arr, i)))

# 自定义函数或用carray.i
n=6
rst_arr = obj.new_floatArray(n)
arr = obj.new_floatArray(n)

test_Add_C_PulsPulse(obj,None,None,rst_arr,arr,n)
#
obj.delete_floatArray(rst_arr)
obj.delete_floatArray(arr)

#类操作数组:
a1=obj.FloatArrClass(6)
a2=obj.FloatArrClass(6)

size1=a1.getSize()
size2=a2.getSize()

rst_arr=a1.getFloatPointer()
arr=a2.getFloatPointer()

test_Add_C_PulsPulse(obj,a1,a2,rst_arr,arr,n)


 下载源代码:https://download.csdn.net/download/tcy23456/12889522


使用说明:
1.在VS2017中修改代码(也可不修改运行作者的代码)
2.在Hello.i右键编译
3.Vs中:生成--重新生成解决方案

打开pycharm:
运行Swig\test_swig.py

注意:
在运行前要修改路径:我的是将这两个文件放在桌面C:\Users\Administrator\Desktop
相关环境变量要事先配置好。
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页