简体   繁体   English

用SWIG操纵C中的Numpy数组

[英]Manipulate Numpy array inside C with SWIG

Trying to pass a Numpy array to a C method and modify its content there, is it even possible? 试图将Numpy数组传递给C方法并在那里修改其内容,是否有可能? The idea is to do as little data copying (speed and memory reasons) as possible. 这样做的想法是尽可能少地复制数据(速度和内存原因)。

Trying out something like this currently: 目前正在尝试这样的事情:

test.c : test.c

void testMethod(int** values) {
  // code
  *values = other_pointer;
}

test.i : 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);

I modified the numpy.i file adding: 我修改了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);
}

Running it: 运行它:

input = numpy.array([1,2,3])
test.testMethod(input)

Works, ie it compiles and I can print the contents of the array in C but content of input stays the same. 有效,即可以编译,我可以在C中打印数组的内容,但输入内容保持不变。

To answer my own question, one a bit hacky way would be to change the typemap to something like this: 为了回答我自己的问题,一种有点怪异的方法是将类型映射更改为以下形式:

%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: after a bit of testing the above would work but produce Segmentation Fault exception if we reuse the Python input array. @Edit:经过一些测试,上面的方法可以工作,但是如果我们重新使用Python input数组,则会产生Segmentation Fault异常。 The solution is to change the mapping type from ARGOUT_ARRAY1 to INPLACE_ARRAY1 . 解决方案是将映射类型从ARGOUT_ARRAY1INPLACE_ARRAY1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM