ctypes与C++ DLL结构体传参取值不匹配问题排查
问题根源
两侧结构体值错位的核心原因是内存对齐规则不匹配:
- C++侧通过
#pragma pack(push, 1)强制结构体按1字节对齐,成员之间没有任何填充字节 - Python侧ctypes的
Structure默认使用平台自然对齐规则(通常按成员自身长度对齐,比如c_uint要求4字节对齐),会在成员之间自动插入填充字节,导致每个字段的内存偏移和C++侧完全不一致,读取时自然会出现值错乱。
你可以直接打印两侧结构体长度验证:C++侧sizeof(Status)结果为36字节,未修改的Python侧sizeof(Status)结果会大于36字节,长度不一致就证明内存布局不匹配。
修复方法
在ctypes定义的Status类中显式添加_pack_ = 1属性,强制和C++侧使用完全一致的1字节对齐规则即可。
修正后的Python代码:
from ctypes import Structure, c_ubyte, c_uint, c_char, c_int, POINTER, byref class Status(Structure): _pack_ = 1 # 对齐规则与C++侧#pragma pack(1)保持一致 _fields_ = [ ("mode", c_ubyte), ("state", c_ubyte), ("info", c_uint), ("errorCode", c_uint), ("selected", c_ubyte), ("id", c_char * 25) ] status = Status() getStatus = dll.GetStatus getStatus.argtypes = [c_int, POINTER(Status)] getStatus.restype = c_int ret = getStatus(someid, byref(status))
修改完成后再次打印两侧结构体长度,会发现均为36字节,此时各字段读取值就会完全匹配。
补充:如果需要读取
id字段的字符串内容,使用status.id.decode("对应编码")即可(通常为gbk或utf-8,根据DLL实际实现确定)。
内容的提问来源于stack exchange,提问作者Arki99
相关产品推荐
相关产品推荐

