Ctypes:将返回指针转换为数组或Python列表的快速方法 [英] Ctypes: fast way to convert a return pointer to an array or Python list

查看:544
本文介绍了Ctypes:将返回指针转换为数组或Python列表的快速方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using ctypes to pass an array pointer to a dll and return a pointer to an array of doubles that was created using malloc in the dll. On return to Python, I need a fast way to convert the pointer to an array or Python list.

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

I can use this list comp, but it's slow because there are 320,000 data points:

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

理想情况下,我会在Python中创建数组并将其传递给dll,但是我必须使用dll中的malloc来创建它,因为这是一个动态数组,在此之前我不知道会有多少个数据元素(尽管返回指针还返回数据元素的数量,因此我知道返回到Python时有多少个元素)-我使用realloc在dll中动态扩展数组大小;我可以将realloc与Python数组一起使用,但是不能保证最后调用free()可以正常工作。

Ideally I would create the array in Python and pass it to the dll, but I have to create it using malloc in the dll because this is a dynamic array where I don't know beforehand how many data elements there will be (although the return pointer also returns the number of data elements, so I know how many there are on return to Python) -- I use realloc to extend the array size dynamically in the dll; I can use realloc with a Python array, but a call to free() at the end is not guaranteed to work.

Here is the relevant Python code:

CallTest = hDLL.Main_Entry_fn
CallTest.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.c_int64]
CallTest.restype = ctypes.POINTER(ctypes.c_double)
ret_ptr = CallTest(DataArray, number_of_data_points)
list_of_results = [ret_ptr[i] for i in range(320000)]

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

So my question is: what is the fastest way to convert a pointer returned from a dll to a Python list or array? The method shown above is too slow.

非常感谢。

推荐答案

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

Slicing a ctypes array or pointer will automatically produce a list:

list_of_results = ret_ptr[:320000]

取决于您的意思是将指针转换为数组以及可以使用的输出类型,则可能会做得更好。例如,您可以直接创建一个由缓冲区支持的NumPy数组,而无需复制数据:

Depending on what you mean by "convert the pointer to an array" and what output types you can work with, you may be able to do better. For example, you can make a NumPy array backed by the buffer directly, with no data copying:

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)

如果您在仍然需要缓冲区的同时取消分配缓冲区,这当然会令人震惊。

This will of course break horribly if you deallocate the buffer while something still needs it.

这篇关于Ctypes:将返回指针转换为数组或Python列表的快速方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆