Python ctypes中的指针和数组

时间:2009-09-01 15:38:20

标签: python arrays pointers ctypes

我有一个包含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?

4 个答案:

答案 0 :(得分:54)

您可以使用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>
>>> 

答案 1 :(得分:1)

您可以强制转换结果,但是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)

答案 2 :(得分:0)

第一个答案的解决方案的更紧凑版本:

>>> from ctypes import *
>>> x = (c_ulong*5)()
>>> x
<__main__.c_ulong_Array_5 object at 0x7f96852bd0e0>
>>> cast(x, POINTER(c_ulong))
<__main__.LP_c_ulong object at 0x7f96852bd170>

答案 3 :(得分:-1)

解决方案中存在拼写错误。为了获得指向ulong数组的指针,您需要转换为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>