Ctypes:将返回指针转换为数组或Python列表的快速方法

时间:2018-02-21 19:26:21

标签: python arrays ctypes

我正在使用ctypes将数组指针传递给dll,并返回指向使用dll中的malloc创建的双精度数组的指针。在返回Python时,我需要一种快速的方法将指针转换为数组或Python列表。

我可以使用这个列表comp,但它很慢,因为有320,000个数据点:

a = [int(x) for x in input().split()]
b = [int(x) for x in input().strip().split(' ')]

def results(a,b):
    highest = b[0]
    lowest = b[0]
    highest_changes = 0
    lowest_changes = 0
    for i in range(1,len(b)):
        if b[i] > b[i-1] and b[i] > highest:
            highest = b[i]
            highest_changes += 1
        if b[i] < b[i-1] and b[i] < lowest:
            lowest = b[i]
            lowest_changes += 1
    return highest_changes, lowest_changes

理想情况下,我会在Python中创建数组并将其传递给dll,但我必须在dll中使用malloc创建它,因为这是一个动态数组,我事先不知道有多少数据元素(虽然返回指针也返回数据元素的数量,所以我知道有多少返回Python) - 我使用realloc在dll中动态扩展数组大小;我可以在Python数组中使用realloc,但最后调用free()并不能保证工作。

list_of_results = [ret_ptr[i] for i in range(320000)]

所以我的问题是:将从dll返回的指针转换为Python列表或数组的最快方法是什么?上面显示的方法太慢了。

非常感谢。

1 个答案:

答案 0 :(得分:3)

切片ctypes数组或指针将自动生成一个列表:

list_of_results = ret_ptr[:320000]

根据“将指针转换为数组”的含义以及可以使用的输出类型,您可以做得更好。例如,您可以直接使缓冲区支持NumPy数组,而无需复制数据:

buffer_as_ctypes_array = ctypes.cast(ret_ptr, ctypes.POINTER(ctypes.c_double*320000))[0]
buffer_as_numpy_array = numpy.frombuffer(buffer_as_ctypes_array, numpy.float64)

如果你在需要它的时候释放缓冲区,这当然会破坏。