如何使用 ctypes 确定以 NULL 结尾的字符串的长度?

How to determine the length of a NULL-terminated string with ctypes?

我正在通过 ctypes 访问一个函数,该函数 return 是指向以 NULL 结尾的字符串(array/vector 个字符)的指针。内存由函数分配(不在我的控制之下)。问题是,它 return 没有关于其长度的任何信息。我想出的东西(以及有效的东西),受到我将在 C 中做的事情的松散启发,看起来有点古怪:

import ctypes

def get_length_of_null_terminated_string(in_pointer):
    datatype = ctypes.c_char
    datatype_size = ctypes.sizeof(datatype)
    terminator = b'\x00'
    length = 0
    char_pointer = ctypes.cast(in_pointer, ctypes.POINTER(datatype))
    STRING_MAX = 1024
    while True:
        if char_pointer.contents.value == terminator:
            break
        if length > STRING_MAX:
            raise
        void_pointer = ctypes.cast(char_pointer, ctypes.c_void_p)
        void_pointer.value += datatype_size
        char_pointer = ctypes.cast(void_pointer, ctypes.POINTER(datatype))
        length += 1
    return length

def test():
    test_string = b'Hello World!'
    print('Actual length: %d' % len(test_string))
    test_buffer = ctypes.create_string_buffer(test_string)
    test_pointer = ctypes.cast(test_buffer, ctypes.c_void_p)
    print('Measured length: %d' % get_length_of_null_terminated_string(test_pointer))

if __name__ == '__main__':
    test()

有更好的方法吗?

特别是,我找不到摆脱两个 cast 语句的方法。看来我只能增加 c_void_p 对象的地址(通过其 value 属性),而指向 c_char.

的指针似乎不可能

感谢@abarnert 在评论中提出这个建议。

使用 ctypes.POINTER(ctypes.c_char) 在这里是一种错误的方法。将我的指针投射到 ctypes.c_char_p 相反会有所帮助。 Python 的 len 方法可以简单地应用于 c_char_p.

实例的 value 属性

按照我原来的例子,解决方案如下所示:

def get_length_of_null_terminated_string_better(in_pointer):
    return len(ctypes.cast(in_pointer, ctypes.c_char_p).value)