【问题标题】:Big arrays with numpy ctypes具有 numpy ctypes 的大数组
【发布时间】:2018-04-12 18:18:51
【问题描述】:

我有一个接收 int 数组的 C++ 函数,我正在使用 ctypesnumpy 为它制作一个 python 包装器。这是一个最小的例子:

copy.cpp

#include <vector>

extern "C" std::vector<int>* copy_vec(int* array, int size){    
    std::vector<int>* vec = new std::vector<int>(size);
    for (int i=0; i<size; i++){
        vec->push_back(array[i]);
    }
    return vec;
}

copy.py

import ctypes as ct
import numpy as np

INT_POINTER = ct.POINTER(ct.c_int)

_lib = ct.cdll.LoadLibrary('./libcopy.dll')
_lib.copy_vec.argtypes = [INT_POINTER, ct.c_int]

def copy(nums):
    size = len(nums)
    nums_c = np.array(nums).ctypes.data_as(INT_POINTER)
    vector = _lib.copy_vec(nums_c, size)
    return vector

array =[12]*1000000
copy(array)

这会产生以下错误消息:

---------------------------------------------------------------------------
WindowsError                              Traceback (most recent call last)
<ipython-input-2-752101759a61> in <module>()
      1 array =[12]*1000000
----> 2 copy(array)

<ipython-input-1-f18316d64ae3> in copy(nums)
     10     size = len(nums)
     11     nums_c = np.array(nums).ctypes.data_as(INT_POINTER)
---> 12     vector = _lib.copy_vec(nums_c, size)
     13 
     14     return vector

WindowsError: exception: access violation reading 0x08724020

此代码适用于像 array =[12]*100 这样的小数组,但在使用大数组时会失败。

【问题讨论】:

    标签: python arrays numpy ctypes


    【解决方案1】:

    找了很久才发现问题。

    我用np.array(nums) 创建了一个数组,然后用.ctypes.data_as(INT_POINTER) 创建了一个指向该数组的ctypes 指针。由于没有保留对 numpy 数组的引用,因此指针将指向一个临时变量。解决这个问题的方法是在 python 中保持对数组的引用。

    nums_a = np.array(nums)
    nums_c = nums_a.ctypes.data_as(INT_POINTER)
    

    完整的功能是:

    def copy(nums):
        size = len(nums)
        nums_a = np.array(nums)
        nums_c = nums_a.ctypes.data_as(INT_POINTER)  
        vector = _lib.copy_vec(nums_c, size)
    
        return vector
    

    对于小型阵列,可能有足够的时间在其内存被回收之前完成复制阵列,但对于大型阵列,这种内存回收可能具有更高的优先级。

    更多内容请关注numpy.ndarray.ctypes

    【讨论】:

    • 如果您刚开始编写代码并且仍然可以更改 Python 和 C++ 之间的互操作方式,我强烈建议您使用名为 PyBind 的 C++ 库。它的设置非常简单,从 pip 安装它,您可以轻松地传递 Numpy 数组,甚至是自定义类型。我用一个简单的工作示例和解释回答了一个问题here
    猜你喜欢
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 2011-05-20
    • 2010-10-29
    • 1970-01-01
    相关资源
    最近更新 更多