如何从Python向C函数传递包含\x00的字节数据?
解决含\x00的Python字节串完整传递给C函数的问题
核心问题在于C语言的strlen()会把\x00(空字符)当作字符串结束符,导致只计算到第一个\x00的位置,截断了后续数据。要完整传递带空字符的字节数据,必须显式传递数据的实际长度,不能依赖字符串结束符。
具体修改步骤
1. 修改C动态库的send函数接口
给send函数新增一个长度参数,直接用这个长度调用SSL_write,不再依赖strlen():
#include <openssl/ssl.h> // 新增size_t类型的长度参数len void send(const char *msg, size_t len) { // 直接传入完整长度len,不再用strlen(msg) SSL_write(ssl, msg, len); }
注:把
char*改成const char*是更规范的写法,表明函数不会修改传入的字符串内容。
2. 调整Python端的调用代码
更新函数参数类型声明,同时传递字节串的实际长度:
from ctypes import cdll, c_char_p, c_size_t msg = b'aaa\x01' + b'\x00' + b'\x23\x45cc' dl = cdll.LoadLibrary lib = dl("./test.so") # 声明函数的参数类型:第一个是字符指针,第二个是无符号整数类型的长度 lib.send.argtypes = (c_char_p, c_size_t) # 传递字节串本身,以及它的实际长度(len(msg)直接拿到字节总数) lib.send(msg, len(msg))
特殊情况处理(无法修改C函数时)
如果由于某些原因不能修改test.so的代码,只能通过变通方式处理:比如在Python端把\x00替换成一个不会出现在正常数据中的特殊字符,在C函数里接收到后再替换回\x00。但这种方式容易引入冲突,增加复杂度,优先推荐修改C函数接口传递长度。
内容的提问来源于stack exchange,提问作者pipik
相关产品推荐
相关产品推荐

