Return Swig 中 ref 的动态数组
Return dynamic arrays by ref in Swig
我正在使用 swig 将一些代码包装在 c++ 中以用于 Python。
在对输入数组进行一些计算后,我有一个函数可以获取数组和 return 2 个动态数组(该函数通过 ref 获取它们)。
我的问题是输出数组的大小未指定,因为大小取决于输入数组。
我的函数看起来像:
void arrayManipulate(int* inArray, int inLen, int resolution, int* &outArray1, int &outLen1, int* &outArray2, int &outLen2)
我使用 numpy.i 将输入数组转换为 numpy 数组。
但是,如果我想将 numpy 用于 return 带有 ARGOUT 的数组,它就不起作用,因为它假定输出数组的大小是已知的。
module.i:
%module minimal
%{
#include "minimal.h"
#include "numpy/arrayobject.h"
%}
%include numpy.i
%init %{
inport_array();
%}
%apply (int* INARRAY1, int DIM1) {(int* inArray, int inLen)}
%apply (int* ARGOUT_ARRAY1, int DIM1) {(int* &outArray1, int &outLen1), (int* &outArray2, int &outLen2)
%include "minimal.h"
如果我尝试编译它,我会收到以下错误:
File minimal_wrap.cxx: IntelliSense: a value of type "int" could not be assigned to entity od type "int *"
File minimal_wrap.cxx: IntelliSense: a value of type "int *" could not be assigned to entity od type "int **"
如果我从 minimal.i 和 minimal.h(从函数)中删除所有“&”符号,它会编译但会例外 python 以给出输出数组的维数:
TypeError: arrayManipulate takes exactly 4 arguments (2 given)
我想在 python 中使用它,例如:
import minimal
import numpy as np
arr1, arr2 = minimal.arrayManipulate(np.asarray([1,2,3]),100)
我怎样才能让它发挥作用?
这是一个答案,它使用双指针而不是 *&。你可以做一个简单的包装函数来支持这个原型
请注意,返回的数组已分配,并且类型映射会生成一个代理,以确保在 Python 中删除数组时删除这些数组。他们被管理
头文件(test.h):
#pragma once
void fun(int* inArray, int inLen, int resolution,
int** outArray1, int* outLen1,
int** outArray2, int* outLen2);
源文件(test.cpp):
#include "test.h"
#include <malloc.h>
void fun(int* inArray, int inLen, int resolution,
int** outArray1, int* outLen1,
int** outArray2, int* outLen2) {
int _outLen1 = resolution*inLen;
int _outLen2 = resolution*inLen;
int* _outArray1 = (int*)malloc(_outLen1*sizeof(int));
int* _outArray2 = (int*)malloc(_outLen2*sizeof(int));
for (int i = 0 ; i < inLen ; i++) {
for (int j = 0 ; j < resolution ; j++) {
_outArray1[i*resolution+j] = resolution*inArray[i];
_outArray2[i*resolution+j] = resolution*inArray[i];
}
}
// Assign outputs
*outLen1 = _outLen1;
*outLen2 = _outLen2;
*outArray1 = _outArray1;
*outArray2 = _outArray2;
}
接口定义文件(test.i)
%module example
%{
#define SWIG_FILE_WITH_INIT
#include "test.h"
%}
%include "numpy.i"
%init
%{
import_array();
%}
%apply (int* IN_ARRAY1, int DIM1) {(int* inArray, int inLen)}
%apply (int** ARGOUTVIEWM_ARRAY1, int* DIM1) {(int** outArray1, int* outLen1)}
%apply (int** ARGOUTVIEWM_ARRAY1, int* DIM1) {(int** outArray2, int* outLen2)}
%include "test.h"
来自 Python
import numpy as np
import example
a = np.ones(27,dtype=np.int32)
h = example.fun(a,2) # h contains the two outputs
支持例如size_t,在 numpy.i
中搜索此部分
%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
%numpy_typemaps(float , NPY_FLOAT , int)
%numpy_typemaps(double , NPY_DOUBLE , int)
并添加以下内容
%numpy_typemaps(signed char , NPY_BYTE , size_t)
%numpy_typemaps(unsigned char , NPY_UBYTE , size_t)
%numpy_typemaps(short , NPY_SHORT , size_t)
%numpy_typemaps(unsigned short , NPY_USHORT , size_t)
%numpy_typemaps(int , NPY_INT , size_t)
%numpy_typemaps(unsigned int , NPY_UINT , size_t)
%numpy_typemaps(long , NPY_LONG , size_t)
%numpy_typemaps(unsigned long , NPY_ULONG , size_t)
%numpy_typemaps(long long , NPY_LONGLONG , size_t)
%numpy_typemaps(unsigned long long, NPY_ULONGLONG, size_t)
%numpy_typemaps(float , NPY_FLOAT , size_t)
%numpy_typemaps(double , NPY_DOUBLE , size_t)
这将添加更多类型映射以支持使用 size_t 而不是 int 进行索引。
我正在使用 swig 将一些代码包装在 c++ 中以用于 Python。
在对输入数组进行一些计算后,我有一个函数可以获取数组和 return 2 个动态数组(该函数通过 ref 获取它们)。
我的问题是输出数组的大小未指定,因为大小取决于输入数组。
我的函数看起来像:
void arrayManipulate(int* inArray, int inLen, int resolution, int* &outArray1, int &outLen1, int* &outArray2, int &outLen2)
我使用 numpy.i 将输入数组转换为 numpy 数组。
但是,如果我想将 numpy 用于 return 带有 ARGOUT 的数组,它就不起作用,因为它假定输出数组的大小是已知的。
module.i:
%module minimal
%{
#include "minimal.h"
#include "numpy/arrayobject.h"
%}
%include numpy.i
%init %{
inport_array();
%}
%apply (int* INARRAY1, int DIM1) {(int* inArray, int inLen)}
%apply (int* ARGOUT_ARRAY1, int DIM1) {(int* &outArray1, int &outLen1), (int* &outArray2, int &outLen2)
%include "minimal.h"
如果我尝试编译它,我会收到以下错误:
File minimal_wrap.cxx: IntelliSense: a value of type "int" could not be assigned to entity od type "int *"
File minimal_wrap.cxx: IntelliSense: a value of type "int *" could not be assigned to entity od type "int **"
如果我从 minimal.i 和 minimal.h(从函数)中删除所有“&”符号,它会编译但会例外 python 以给出输出数组的维数:
TypeError: arrayManipulate takes exactly 4 arguments (2 given)
我想在 python 中使用它,例如:
import minimal
import numpy as np
arr1, arr2 = minimal.arrayManipulate(np.asarray([1,2,3]),100)
我怎样才能让它发挥作用?
这是一个答案,它使用双指针而不是 *&。你可以做一个简单的包装函数来支持这个原型
请注意,返回的数组已分配,并且类型映射会生成一个代理,以确保在 Python 中删除数组时删除这些数组。他们被管理
头文件(test.h):
#pragma once
void fun(int* inArray, int inLen, int resolution,
int** outArray1, int* outLen1,
int** outArray2, int* outLen2);
源文件(test.cpp):
#include "test.h"
#include <malloc.h>
void fun(int* inArray, int inLen, int resolution,
int** outArray1, int* outLen1,
int** outArray2, int* outLen2) {
int _outLen1 = resolution*inLen;
int _outLen2 = resolution*inLen;
int* _outArray1 = (int*)malloc(_outLen1*sizeof(int));
int* _outArray2 = (int*)malloc(_outLen2*sizeof(int));
for (int i = 0 ; i < inLen ; i++) {
for (int j = 0 ; j < resolution ; j++) {
_outArray1[i*resolution+j] = resolution*inArray[i];
_outArray2[i*resolution+j] = resolution*inArray[i];
}
}
// Assign outputs
*outLen1 = _outLen1;
*outLen2 = _outLen2;
*outArray1 = _outArray1;
*outArray2 = _outArray2;
}
接口定义文件(test.i)
%module example
%{
#define SWIG_FILE_WITH_INIT
#include "test.h"
%}
%include "numpy.i"
%init
%{
import_array();
%}
%apply (int* IN_ARRAY1, int DIM1) {(int* inArray, int inLen)}
%apply (int** ARGOUTVIEWM_ARRAY1, int* DIM1) {(int** outArray1, int* outLen1)}
%apply (int** ARGOUTVIEWM_ARRAY1, int* DIM1) {(int** outArray2, int* outLen2)}
%include "test.h"
来自 Python
import numpy as np
import example
a = np.ones(27,dtype=np.int32)
h = example.fun(a,2) # h contains the two outputs
支持例如size_t,在 numpy.i
中搜索此部分%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
%numpy_typemaps(float , NPY_FLOAT , int)
%numpy_typemaps(double , NPY_DOUBLE , int)
并添加以下内容
%numpy_typemaps(signed char , NPY_BYTE , size_t)
%numpy_typemaps(unsigned char , NPY_UBYTE , size_t)
%numpy_typemaps(short , NPY_SHORT , size_t)
%numpy_typemaps(unsigned short , NPY_USHORT , size_t)
%numpy_typemaps(int , NPY_INT , size_t)
%numpy_typemaps(unsigned int , NPY_UINT , size_t)
%numpy_typemaps(long , NPY_LONG , size_t)
%numpy_typemaps(unsigned long , NPY_ULONG , size_t)
%numpy_typemaps(long long , NPY_LONGLONG , size_t)
%numpy_typemaps(unsigned long long, NPY_ULONGLONG, size_t)
%numpy_typemaps(float , NPY_FLOAT , size_t)
%numpy_typemaps(double , NPY_DOUBLE , size_t)
这将添加更多类型映射以支持使用 size_t 而不是 int 进行索引。