Python中如何读取文件为原始字符串字面量以适配ctypes函数?
ctypes函数传入文件字节串失败的解决方案
问题背景
使用ctypes调用函数时,出现以下差异现象:
- 用
r前缀定义原始字符串字面量,编码为字节串传入后函数执行成功; - 直接以二进制模式读取文件得到字节串,或直接定义字节串字面量传入,函数均执行失败。
需要将文件内容读取为与原始字符串字面量等价的形式。
测试代码:
if __name__ == '__main__': a = r"\x00hello" with open('some_file', 'rb') as f: # some_file中仅包含"\x00hello" b = f.read() c = b"\x00hello" x = CtypeObj.Function(a.encode('utf-8', errors='ignore')) # 执行成功! y = CtypeObj.Function(b) # 执行失败! z = CtypeObj.Function(c) # 执行失败!
核心原因
不同方式生成的字节串实际内容完全不同:
a.encode('utf-8')生成b'\\x00hello':共9个字节,对应字符\、x、0、0、h、e、l、l、o的UTF-8编码;c = b"\x00hello"生成b'\x00hello':共6个字节,对应**空字节(0x00)**加上hello的5个字节;- 若文件保存的是转义后的二进制内容(如实际包含空字节),读取的
b会和c一致,不符合函数预期格式。
解决方案
根据文件实际保存的内容类型,选择对应处理方式:
场景1:文件保存的是字面量文本(如直接输入的\x00hello)
用文本模式读取文件,再编码为UTF-8字节串,即可得到与原始字符串编码后一致的结果:
with open('some_file', 'r', encoding='utf-8') as f: # 读取文本并去除可能的换行符,再编码为字节串 b = f.read().strip().encode('utf-8') CtypeObj.Function(b) # 执行成功
场景2:文件保存的是二进制内容(如包含空字节0x00)
需要将二进制内容转换为字面量转义格式的字节串,可通过repr()函数实现:
with open('some_file', 'rb') as f: b_raw = f.read() # 将二进制内容转为转义字符串,去掉repr生成的前后标识后编码 b_escaped = repr(b_raw)[2:-1].encode('utf-8') CtypeObj.Function(b_escaped) # 执行成功
补充说明
原始字符串r"\x00hello"不会解析\x00为转义序列,而是将其作为普通字符组合处理,编码后的字节串正好匹配ctypes函数的预期格式。而直接定义字节串或读取二进制文件,会将\x00解析为实际空字节,与函数要求的格式不匹配,导致执行失败。
内容的提问来源于stack exchange,提问作者meowcat
相关产品推荐
相关产品推荐

