Python 如何管理ctypes中的嵌套结构? 我有一个C++库,具有以下的结合: typedef union DVersion { uint32_t VMask; struct { uint8_t Build; uint8_t Rev; uint8_t Min; uint8_t Maj; }; }DATA_VER;

Python 如何管理ctypes中的嵌套结构? 我有一个C++库,具有以下的结合: typedef union DVersion { uint32_t VMask; struct { uint8_t Build; uint8_t Rev; uint8_t Min; uint8_t Maj; }; }DATA_VER;,python,c++,python-3.x,ctypes,Python,C++,Python 3.x,Ctypes,还有另一个结构,其中包含一个字段 typedef struct DH { uint16_t Tok1; DATA_VER DVersion; uint16_t DataCount; }DataHeader 当我在C++上使用这个DLL时,它也很好,C上也是如此,所以DLL被验证了。 当我使用ctypes处理Python时,看起来字节数不一致 我尝试过这些解决方案 解决方案1: 解决方案2: 在这两种情况下,Tok1的值都正确,但DVersion和DataCo

还有另一个结构,其中包含一个字段

typedef struct DH
{
    uint16_t   Tok1;
    DATA_VER   DVersion;
    uint16_t   DataCount;
}DataHeader

当我在C++上使用这个DLL时,它也很好,C上也是如此,所以DLL被验证了。 当我使用ctypes处理Python时,看起来字节数不一致

我尝试过这些解决方案

解决方案1:

解决方案2:

在这两种情况下,Tok1的值都正确,但DVersion和DataCount显示不正确。在我看来,由于嵌套结构,字节未对齐

你能告诉我我做错了什么吗?非常感谢您的支持

我发现了

即使ctypes文档中没有明确说明,也应该包括 _在您的结构上打包=1。就我而言:

class VER_Struct(Structure):
    _fields_ = [("Build", c_uint8),
                ("Rev",  c_uint8),
                ("Min",  c_uint8),
                ("Maj",  c_uint8)]

class DATA_VER(Union):
    _anonymous_ = ("u",)
    _fields_ = [("VMask", c_uint32, 32), 
                ("u",VER_Struct)]

class DataHeader(Structure):
    _pack_   = 1
    _fields_ = [("Tok1", c_uint16, 16),
                ("DVersion", DATA_VER),
                ("DataCount", c_uint16, 16)]

希望这对其他人有帮助

也许检查什么是填充和对齐会有帮助吗?谢谢,你知道我在哪里可以找到关于ctypes对齐的信息吗?很高兴它有帮助,我以前从未使用过ctypes:在这种解析器中,你可以凭经验记住检查接口上的两件事:1。填充,2。Endianness通常只有在结构已打包时才需要打包。C++/C代码中是否有pragma pack或等效语句?我遇到的问题是,我使用的是一个外部DLL,我只有.H和DLL。通常,.H文件会有结构定义和打包声明(如果有的话)。
class DATA_VER(Union):
    _fields_ = [("VMask", c_uint32, 32), 
                ("Build", c_uint8),
                ("Rev",  c_uint8),
                ("Min",  c_uint8),
                ("Maj",  c_uint8)]

class DataHeader(Structure):
    _fields_ = [("Tok1", c_uint16, 16),
                ("DVersion", DATA_VER),
                ("DataCount", c_uint16, 16)]
class VER_Struct(Structure):
    _fields_ = [("Build", c_uint8),
                ("Rev",  c_uint8),
                ("Min",  c_uint8),
                ("Maj",  c_uint8)]

class DATA_VER(Union):
    _anonymous_ = ("u",)
    _fields_ = [("VMask", c_uint32, 32), 
                ("u",VER_Struct)]

class DataHeader(Structure):
    _pack_   = 1
    _fields_ = [("Tok1", c_uint16, 16),
                ("DVersion", DATA_VER),
                ("DataCount", c_uint16, 16)]