python:ctypes,在python中读取POINTER(c_char)

时间:2019-03-11 13:48:19

标签: python ctypes

我有一个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]那样对其进行索引,其中fooPOINTER(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函数是否会更容易编写。

1 个答案:

答案 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!'