我正在使用ctypes在Python中实现C ++函数。 C ++函数应该返回一个指向数组的指针。不幸的是我还没弄明白,如何在Python中访问数组。我试过numpy.frombuffer,但那不成功。它只返回了一个任意数字的数组。显然我没有正确使用它。这是一个大小为10的数组的简单示例:
function.cpp的内容:
extern "C" int* function(){
int* information = new int[10];
for(int k=0;k<10;k++){
information[k] = k;
}
return information;
}
wrapper.py的内容:
import ctypes
import numpy as np
output = ctypes.CDLL('./library.so').function()
ArrayType = ctypes.c_double*10
array_pointer = ctypes.cast(output, ctypes.POINTER(ArrayType))
print np.frombuffer(array_pointer.contents)
编译我正在使用的C ++文件:
g++ -c -fPIC function.cpp -o function.o
g++ -shared -Wl,-soname,library.so -o library.so function.o
对于在Python中访问数组值,我有什么建议吗?
答案 0 :(得分:19)
您的python代码将在经过一些小修改后起作用:
import ctypes
f = ctypes.CDLL('./library.so').function
f.restype = ctypes.POINTER(ctypes.c_int * 10)
print [i for i in f().contents] # output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
基本上有两处变化:
删除与numpy相关的代码和ctypes.cast
调用,因为我们不需要它们。
将返回类型指定为ctypes.POINTER(ctypes.c_int * 10)
。
默认情况下,假定外部函数返回C int类型,因此我们需要将其更改为所需的指针类型。
new
ed数组从C代码返回到Python代码似乎不合适。谁和什么时候会释放记忆?最好在Python代码中创建数组并将它们传递给C代码。这样很明显,Python代码拥有数组,并负责创建和回收它们的空间。
答案 1 :(得分:15)
function.cpp
返回一个int数组,而wrapper.py
尝试将它们解释为双精度数。将ArrayType
更改为ctypes.c_int * 10
,它应该有效。
自己使用np.ctypeslib
代替frombuffer
可能更容易。这应该看起来像
import ctypes
from numpy.ctypeslib import ndpointer
lib = ctypes.CDLL('./library.so')
lib.function.restype = ndpointer(dtype=ctypes.c_int, shape=(10,))
res = lib.function()