尝试将Numpy数组传递给C方法并在那里修改其内容,它甚至可能吗?我们的想法是尽可能少地进行数据复制(速度和内存原因)。
目前尝试这样的事情:
test.c的:
void testMethod(int** values) {
// code
*values = other_pointer;
}
test.i :
/* File : test.i */
%module test
%{
#define SWIG_FILE_WITH_INIT
%}
%include "numpy.i"
%init %{
import_array();
%}
%{
extern void testMethod(int** values);
%}
%apply (int **ARGOUT_ARRAY1) {int **values};
extern void testMethod(int** values);
我修改了 numpy.i 文件,添加:
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE **ARGOUT_ARRAY1)
(PyArrayObject* array=NULL, int is_new_object=0, DATA_TYPE* temp=NULL)
{
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
temp = (DATA_TYPE*) array_data(array);
$1 = &temp;
}
%typemap(argout)
(DATA_TYPE** ARGOUT_ARRAY1)
{
$result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
}
运行它:
input = numpy.array([1,2,3])
test.testMethod(input)
工作,即它编译,我可以用C打印数组的内容,但输入的内容保持不变。
答案 0 :(得分:0)
要回答我自己的问题,一个有点hacky的方法是将类型映射更改为:
%typemap(in,
fragment="NumPy_Fragments")
(DATA_TYPE **ARGOUT_ARRAY1)
(PyArrayObject* array=NULL, int is_new_object=0, PyArrayObject_fields* temp=NULL)
{
array = obj_to_array_contiguous_allow_conversion($input,
DATA_TYPECODE,
&is_new_object);
if (!array) SWIG_fail;
temp = (PyArrayObject_fields*)array;
$1 = (DATA_TYPE**) &temp->data;
}
%typemap(argout)
(DATA_TYPE** ARGOUT_ARRAY1)
{
$result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
}
@Edit:经过一些测试后,如果我们重用Python input
数组,上面的工作会有效,但会产生Segmentation Fault异常。解决方案是将映射类型从ARGOUT_ARRAY1
更改为INPLACE_ARRAY1
。