2013-02-15 257 views
15

我正在使用ctypes在Python中实现C++函数。 C++函数应该返回一个指向数组的指针。不幸的是,我还没有想出如何在Python中访问数组。我试过numpy.frombuffer,但那并不成功。它只是返回一个任意数字的数组。显然我没有正确使用它。这里是尺寸为10的阵列的简单的例子:function.cpp的如何使用ctypes将数组从C++函数返回到Python

内容:wrapper.py的

extern "C" int* function(){ 
int* information = new int[10]; 
for(int k=0;k<10;k++){ 
    information[k] = k; 
} 
return information; 
} 

内容:

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

当然,我忘了导入一些特定的ctypes功能,如c_double和POINTER。我只是忘了在这里添加它们。 – dolby 2013-02-15 02:38:38

回答

12

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() 
+0

我也导入了c_int并替换了c_double,但python现在只打印了一个只有5个元素的数组,并且这些值仍然是错误的。这很奇怪。 – dolby 2013-02-15 03:10:12

+0

非常好,非常感谢!它现在有效。 Python只给了我警告“[...] RuntimeWarning:无效的PEP 3118格式字符串:' dolby 2013-02-15 03:28:34

+0

这里有一点点的死神......当你完成它时,你会如何删除内存? – XapaJIaMnu 2017-01-05 18:34:01

17

一些小的修改后的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] 

基本上有两个变化:

  1. 删除numpy的相关代码和ctypes.cast通话因为我们不需要它们。

  2. 指定返回类型为ctypes.POINTER(ctypes.c_int * 10)

    默认情况下,外部函数被假定为返回C int类型,因此我们需要将其更改为所需的指针类型。

顺便说一句,从C代码返回一个new ed数组似乎是不合适的。谁和何时将释放内存?最好在Python代码中创建数组并将它们传递给C代码。这种方式很明显,Python代码拥有数组并负责创建和回收它们的空间。

+2

你能指出我们如何在python中创建这样一个数组,并将它的指针传递给C? – shahensha 2015-07-21 05:19:15

+0

@Shahensha我对int/float数组所做的事情是使用numpy数组,以及嵌入的ctypes接口('data_as') – Adversus 2016-04-26 14:19:31

+0

这里有一点点的巫术......当完成它时,你会如何删除内存? – XapaJIaMnu 2017-01-05 18:35:48