我有一个从dll导入的函数,并在ctypes中定义。我将restype
设为c_void_p
。所以现在当我调用该函数时,它返回指向32byte字节数组的指针。如何将此指针转换为Python字节类型?
这是函数(来自OpenSSL的HMAC
):
self.HMAC = self._lib.HMAC
self.HMAC.restype = ctypes.c_void_p
self.HMAC.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p]
编辑:我尝试用c_void_p
替换c_char_p
。我得到了一些结果,但c_char_p
表示空终止字符串,因此结果在第一个00h处被剪切。如果HMAC
在结果中没有任何零,那么它就完美无缺。但这仍然无法解决我的问题。
答案 0 :(得分:2)
使用ctypes.c_void_p
作为返回类型通常是错误的。
对于非空终止字符串,您应该将其设置为正确大小的字符数组;在你的情况下是32,所以ctypes.c_char * 32
。 restype
是指向此的指针,因此将其包装在ctypes.POINTER
。
您可以使用bytes
(或value
;此上下文中的相同内容)属性(raw
来访问返回的值作为contents
对象。
这是一个使用crypt(3)
的实际示例,它返回一个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'