Python ctypes如何处理含中间\0的c_char_p?如何获取含\0的完整字符串?
关于Python ctypes模块处理含空字符字符串的问题解答
嘿,这两个问题我刚好熟得很,给你详细唠唠:
问题1:Python的ctypes模块在遇到字符串中间包含\0(空字符)时,会如何处理c_char_p类型?
其实ctypes.c_char_p对应的是C语言里的char*类型,而C语言的字符串规则就是以\0作为结束标志。所以当你把包含中间空字符的字节串传给c_char_p后,它的.value属性在读取内容时,会从起始位置开始,一碰到第一个\0就立刻停止,只返回\0之前的部分。
就像你给出的示例:
>>> import ctypes >>> c=b'hello \0 world' >>> a=ctypes.c_char_p(c) >>> a.value b'hello '
本质就是因为C风格字符串的终止规则,c_char_p的.value严格遵循这个逻辑,碰到中间的空字符就直接截断。
问题2:如何获取包含\0的完整字符串?
要拿到带\0的完整内容,有两种常用方法:
方法一:使用ctypes.create_string_buffer
这个函数会创建一个可修改的字符缓冲区,它不会因为中间的\0截断内容。你可以通过.raw属性获取整个缓冲区的字节数据,或者指定长度来读取原内容:
import ctypes c = b'hello \0 world' # 方式1:直接传入字节串创建缓冲区(会自动添加一个终止\0,需截取原长度) buf = ctypes.create_string_buffer(c) full_content = buf.raw[:len(c)] print(full_content) # 输出 b'hello \0 world' # 方式2:指定缓冲区大小为原字节串长度,再复制内容进去 buf = ctypes.create_string_buffer(len(c)) ctypes.memmove(buf, c, len(c)) print(buf.raw) # 输出 b'hello \0 world'
方法二:使用ctypes.string_at
如果你已经有了c_char_p对象,并且知道原字符串的长度,可以用string_at直接从内存地址读取指定长度的内容,绕过C风格字符串的终止规则:
import ctypes c = b'hello \0 world' a = ctypes.c_char_p(c) # 传入地址和长度,读取完整内容 full_str = ctypes.string_at(a, len(c)) print(full_str) # 输出 b'hello \0 world'
内容的提问来源于stack exchange,提问作者LiuQiu
相关产品推荐
相关产品推荐

