繁体   English   中英

用SWIG操纵C中的Numpy数组

[英]Manipulate Numpy array inside C with SWIG

试图将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中打印数组的内容,但输入内容保持不变。

为了回答我自己的问题,一种有点怪异的方法是将类型映射更改为以下形式:

%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_ARRAY1INPLACE_ARRAY1

暂无
暂无

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

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