尝试将 Numpy 数组传递给 C 方法并在那里修改其内容,这甚至可能吗?这个想法是尽可能少地进行数据复制(速度和内存原因)。
目前正在尝试这样的事情:
测试.c:
void testMethod(int** values) {
// code
*values = other_pointer;
}
测试.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 中打印数组的内容,但输入的内容保持不变。
最佳答案
为了回答我自己的问题,一种有点老套的方法是将类型映射更改为如下所示:
%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
。
关于python - 使用 SWIG 在 C 中操作 Numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49524445/