Python 函数返回指向数组的指针和结果。如何访问此数据

Python 函数返回指向数组的指针和结果。如何访问此数据,python,ctypes,Python,Ctypes,我有一个从dll导入并在ctypes中定义的函数。我将restype设置为c\u void\u p。现在,当我调用函数时,它返回指向32字节字节数组的指针。如何将此指针转换为Python字节类型 下面是函数(它是OpenSSL的HMAC): 编辑:我尝试用c\u char\u p替换c\u void\u p。我得到了一些结果,但是c\u char\u p表示以null结尾的字符串,因此结果在第一个00h处被剪切。如果HMAC在结果中没有任何零,则它工作正常。但这仍然不能解决我的问题。使用ctyp

我有一个从dll导入并在ctypes中定义的函数。我将
restype
设置为
c\u void\u p
。现在,当我调用函数时,它返回指向32字节字节数组的指针。如何将此指针转换为Python字节类型

下面是函数(它是OpenSSL的
HMAC
):


编辑:我尝试用
c\u char\u p
替换
c\u void\u p
。我得到了一些结果,但是
c\u char\u p
表示以null结尾的字符串,因此结果在第一个00h处被剪切。如果
HMAC
在结果中没有任何零,则它工作正常。但这仍然不能解决我的问题。

使用
ctypes.c\u void\u p
作为返回类型通常是错误的

对于非nul终止的字符串,应将其设置为大小正确的字符数组;32在您的情况下,所以
ctypes.c_char*32
restype
是指向此的指针,因此将其包装在
ctypes.pointer

您可以使用该指针的
内容的
属性
value
(或
raw
;在本上下文中也是一样)作为
字节
对象访问返回值

下面是一个实际示例,使用返回13个字符的字符串:

>>> import ctypes
>>> crypt = ctypes.CDLL('libcrypt.so').crypt
>>> crypt.argtypes = ctypes.c_char_p, ctypes.c_char_p
>>> crypt.restype = ctypes.POINTER(ctypes.c_char * 13)
>>> crypt('tea', 'ea')
<__main__.LP_c_char_Array_13 object at 0x7f7d464f2200>
>>> crypt('tea', 'ea').contents
<__main__.c_char_Array_13 object at 0x7f7d464f2290>
>>> crypt('tea', 'ea').contents.value
b'eauWokonZwxw2'
>>导入ctypes
>>>crypt=ctypes.CDLL('libcrypt.so').crypt
>>>crypt.argtypes=ctypes.c\u char\u p,ctypes.c\u char\u p
>>>crypt.restype=ctypes.POINTER(ctypes.c_char*13)
>>>地穴('tea','ea')
>>>地穴('tea','ea')。内容
>>>crypt('tea','ea')。contents.value
b'eauWokonZwxw2'

谢谢。。我成功了。我定义了restype=ctypes.POINTER(ctypes.c_char*32)。后者将其转换为python代码中的字节:返回hmac[0][:32]您可以从
c\u void\p
到正确的类型(然后从那里转到
bytes
),但Cairnarvon是对的,没有理由这样做;只需首先将正确的类型指定为
restype
。@eryksun,很好,re:pointer。由于C的指针衰减,我忘记了它,但你是对的。@abarnert:我使用了[:size],因为我使整个python函数更加通用。我将64字节缓冲区声明为restype,以便能够处理不同类型的散列算法(算法名称作为函数参数传递)。最后,我将字节数组剪切为所选哈希的长度。64字节使我能够处理SHA512之前的所有内容。谢谢你的帮助@马瑞克:我想你是想回复艾里克森,不是我。我想Cairnarvon是想回答我,而不是eryksun。但这并不重要。
ctypes
有两种不同类型的字符指针。当指针指向以null结尾的字符串时,请使用
c\u char\p
;当指针指向单个字符或任意字符数组时,请使用
pointer(c\u char)
(也称
LP\u c\u char
)。在封面下它们是相同的,但是
上下文
、索引等做不同的事情。当然,正如Cairnarvon的回答所解释的那样,只使用数组而不是指针更简单,但这与任何数组都是一样的,对char数组并不特殊。
>>> import ctypes
>>> crypt = ctypes.CDLL('libcrypt.so').crypt
>>> crypt.argtypes = ctypes.c_char_p, ctypes.c_char_p
>>> crypt.restype = ctypes.POINTER(ctypes.c_char * 13)
>>> crypt('tea', 'ea')
<__main__.LP_c_char_Array_13 object at 0x7f7d464f2200>
>>> crypt('tea', 'ea').contents
<__main__.c_char_Array_13 object at 0x7f7d464f2290>
>>> crypt('tea', 'ea').contents.value
b'eauWokonZwxw2'