我有一个接收int数组的C ++函数,我正在使用 ctypes 和 numpy 为它创建一个python包装器。这是一个最小的例子:
copy.cpp
bar
copy.py
#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;
}
这会产生以下错误消息:
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
等小型数组,但在使用大型数组时失败。
答案 0 :(得分:1)
很长一段时间后我发现了问题。
我使用array =[12]*100
创建了一个数组,然后使用np.array(nums)
创建了一个指向该数组的ctypes指针。由于没有保留numpy数组的引用,指针将指向临时变量。解决这个问题的方法是在python中保持对数组的引用。
.ctypes.data_as(INT_POINTER)
完整的功能是:
nums_a = np.array(nums)
nums_c = nums_a.ctypes.data_as(INT_POINTER)
对于小型阵列,可能有足够的时间在回收内存之前完成复制数组,但对于大型阵列,这种回收内存可能会更优先。
阅读更多内容