Python ctypes中的指针和数组
我有一个DLL文件,里面有一个C语言的函数,函数的原型是这样的:
int c_read_block(uint32 addr, uint32 *buf, uint32 num);
我想用Python通过ctypes来调用这个函数。这个函数需要一个指向内存块的指针,结果会写到这个内存块里。但是我不知道怎么构造并传递这样一个内存块。ctypes的文档对我帮助不大。
我尝试构造一个数组并通过“引用”传递,像这样:
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呢?
3 个回答
-2
这个解决方案里有个拼写错误。要获取一个指向无符号长整型数组的指针,你需要把它转换成一个 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>
4
你可以把结果转换成其他类型,但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)
68
你可以使用 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>
>>>