我有一个POINTER(c_char)
的ctypes字段(根据文档,c_char_p不适用于我的应用程序:https://docs.python.org/3.7/library/ctypes.html#ctypes.c_char_p)
对于也可能指向二进制数据的通用字符指针,必须使用POINTER(c_char)。
但是,ctypes本身推荐的这种用法似乎有一个缺点,它声称是指向单个字符的指针,但是并非如此,它是指向字节数组的指针。
如何在Python中读取ctypes功能(我知道length
)返回的数组?尝试像foo[0:len]
那样对其进行索引,其中foo
是POINTER(c_char)
会炸毁TypeError: 'c_char' object is not subscriptable
我可以使用print(foo)
或print(foo[0])
来打印字节串的第一个字符
我本以为ctypes.cast
可以工作,但是我不知道如何传递强制类型转换的长度(例如,将地址foo中的前N个字节解释为bytes
对象)
编辑:一些代码。
所以我有一个结构:
class foo(Structure):
_fields_ = [("state", c_int),
("type", c_int),
("len", c_int),
("payload", POINTER(c_char))] # according to th following the python bytes are already unsinged https://bytes.com/topic/python/answers/695078-ctypes-unsigned-char
我还有另一个函数返回一个POINTER(foo)
lib3 = CDLL(....so)
f = lib3.f
f.restype = POINTER(foo)
我打电话给f
,它返回一个POINTER(foo)
:
ptrf = f(....)
然后,我尝试访问ptrf.payload
。以下代码有效:
def get_payload(ptr_to_foo):
val = cast(ptr_to_foo.contents.payload, c_char_p).value
return val[:ptr_to_foo.contents.len]
我愿意
ptrf = f(....)
get_payload(ptrf)
我想知道get_payload
函数是否会更容易编写。
答案 0 :(得分:0)
如果您确实有POINTER(c_char)
类型,则可以下标。将来提供重现您问题的代码:
>>> p = cast(create_string_buffer(b'Hello, world!'),POINTER(c_char))
>>> p
<ctypes.LP_c_char object at 0x000001C2F6B58848>
>>> p[0]
b'H'
>>> p[:14]
b'Hello, world!\x00'
>>> cast(p,c_char_p).value # only if known to be nul-terminated
b'Hello, world!'