如何使用 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)
我正在通过 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)