Python中使用ctypes的回调中的c_void_p参数

Python中使用ctypes的回调中的c_void_p参数,python,callback,ctypes,Python,Callback,Ctypes,我经常使用ctypes,但我遇到了一些无法解释的问题 首先,当我用c_void_p定义回调时,回调将接收一个平坦整数 我看到其他一些帖子提到在使用c_void_p作为返回值时,将c_void_p包装在另一个指针中。所以,我想我可以在回调定义中的参数:POINTER(c_void_p)中试试这个。现在,当调用回调时,我得到了一个指针,但我仍然不知道它是否指向值数据 由于C_void_p指向一个包含二进制数据的缓冲区,我不相信我可以使用C_char_p。我使用传递的长度强制转换到一个无符号字符数组,

我经常使用ctypes,但我遇到了一些无法解释的问题

首先,当我用c_void_p定义回调时,回调将接收一个平坦整数

我看到其他一些帖子提到在使用c_void_p作为返回值时,将c_void_p包装在另一个指针中。所以,我想我可以在回调定义中的参数:POINTER(c_void_p)中试试这个。现在,当调用回调时,我得到了一个指针,但我仍然不知道它是否指向值数据

由于C_void_p指向一个包含二进制数据的缓冲区,我不相信我可以使用C_char_p。我使用传递的长度强制转换到一个无符号字符数组,但是Python告诉我我有一个元组,并且没有可以使用的“contents”或“value”属性


建议?

在回调中将
c\u void\u p
作为整数接收是正常的。它使用简单类型的
getfunc
来进行自动转换——与将
c\u void\p
作为
结构
字段一样。ctypes不会对简单类型的子类进行自动转换,例如
type('my\u void\u p',(c\u void\u p,),{})
。虽然我认为这在这种情况下并不重要

假设您在
p
中有一个整数地址。您可以使用以下任意一种*,将其强制转换为长度为
n
c_char
数组:

这就是说,知道它是一个
char*
,我会定义回调使用
指针(c_char)
。然后通过索引或切片访问缓冲区,例如
p[0]
p[:n]



*
p[n]
相当于
*(p+n)
,其中
*
是解引用运算符,加法使用基于引用对象大小的指针算法。您可以使用
p.contents
而不是
p[0]
,但后者也会调用类型的
getfunc
转换器(如果适用)。

谢谢,@eryksun。我想我需要的是[0]。为什么演员组返回一个元组?ctypes文档中没有对强制转换进行记录:我不明白为什么在对N大小的数组进行强制转换时会得到一个列表/可枚举列表,以及为什么必须执行[0]。[0]是您所指的“取消引用”吗?
buf = cast(p, POINTER(c_char * n))[0]

# 2.6+
buf = (c_char * n).from_address(p)