Python ctypes 中的指针和数组
Posted
技术标签:
【中文标题】Python ctypes 中的指针和数组【英文标题】:Pointers and arrays in Python ctypes 【发布时间】:2010-11-24 16:35:39 【问题描述】:我有一个包含 C 函数的 DLL,其原型如下:
int c_read_block(uint32 addr, uint32 *buf, uint32 num);
我想使用 ctypes 从 Python 调用它。该函数需要一个指向一块内存的指针,它将结果写入其中。我不知道如何构造和传递这么一大块内存。 ctypes 文档帮助不大。
构造一个数组并将其传递给“byref”,如下所示:
cresult = (c_ulong * num)() err = self.c_read_block(addr, byref(cresult), num)给出这个错误信息:
ArgumentError: argument 3: <type 'exceptions.TypeError'>: expected LP_c_ulong instance instead of pointer to c_ulong_Array_2
我猜这是因为 Python ulong 数组与 c uint32 数组完全不同。我应该使用create_char_string
。如果是这样,我如何说服 Python 将该缓冲区“转换”为 LP_c_ulong?
【问题讨论】:
【参考方案1】:您可以使用cast
函数进行投射:)
>>> import ctypes
>>> x = (ctypes.c_ulong*5)()
>>> x
<__main__.c_ulong_Array_5 object at 0x00C2DB20>
>>> ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong))
<__main__.LP_c_ulong object at 0x0119FD00>
>>>
【讨论】:
我用过ctypes
几次,之前在链接文档中遇到过。
为什么我是LP_c_ulong
对象而不是LP_c_ulong_Array_5
对象
LP_c_ulong_Array_5
将是一个地址,该地址指向一个指向uint32
s 数组中第一个元素的地址,而 OP 的函数正在寻找一个指向第一个元素的地址大批。 LP_c_ulong_Array_5
将用于如下功能:int c_read_block(uint32 addr, uint32 *buf[], uint32 num);
【参考方案2】:
您可以转换结果,但ctypes
允许您直接使用数组代替指针。问题是代码中的byref
(相当于指向指针的指针):
所以而不是:
cresult = (c_ulong * num)()
err = self.c_read_block(addr, byref(cresult), num)
尝试:
cresult = (c_ulong * num)()
err = self.c_read_block(addr, cresult, num)
【讨论】:
【参考方案3】:解决方案中有错字。为了获得指向 ulongs 数组的指针,您需要强制转换为 POINTER(list of ulong)
In [33]: ptr = ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong*5))
In [34]: ptr
Out[34]: <__main__.LP_c_ulong_Array_5 at 0x23e2560>
【讨论】:
以上是关于Python ctypes 中的指针和数组的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ctypes 将数组从 C++ 函数返回到 Python
python ctypes中的多维char数组(字符串数组)