python - 使用 SWIG 在 C 中操作 Numpy 数组

标签 python c numpy swig

尝试将 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/

相关文章:

python-3.x - 进行 FFT 的最快方法

python - np.piecewise() 与 math.pow() 一起使用?

python - 替换 Numpy 数组列表中的值

python - 在 Python 中实现插件系统

c - 在 gtk 中出现断言失败错误。

c - 为什么这段代码总是打印 "not matched"?

c - 使用 C 的数学 101

python - 如何在 SQLAlchemy 和 Firebird 的自定义查询中将 Python 列表绑定(bind)为参数?

python - 使用python将多个文本文件合并为一个文本文件

python - 在 Python 的 span 标签中查找多个属性