封送包含布尔值的复杂嵌套结构

毛罗(Mauro)

我需要对几个嵌套结构进行复杂的封送处理,其中包含到其他结构的可变长度数组,因此我决定使用ICustomMarshaler(请参阅此处的JaredPar教程)。但是然后我在C ++中定义的结构有一个问题:

typedef struct AStruct{
    int32_t     a;
    AType*      b;
    int32_t     bLength;
    bool        aBoolean;
    bool        bBoolean;
};

在C#方面,MarshalManagedToNative实现中ICustomMarshaler使用的是:

Marshal.WriteByte(intPtr, offset, Convert.ToByte(aBoolean));
offset += 1;
Marshal.WriteByte(intPtr, offset, Convert.ToByte(bBoolean));

但这没有用,因为我发现C ++结构中的每个布尔都占用2个字节。实际上,在x86中sizeof(AStruct) = 16,不是14。好吧,bool不能保证占用1个字节,因此我尝试了unsigned char和,uint8_t但是大小仍然是16。

现在,我知道我可以使用int32而不是布尔值,但是由于我关心占用的空间,并且有几个包含布尔值的结构会流到磁盘(我使用HDF5文件格式,所以我想使用在H5T_NATIVE_UINT8中定义的布尔值来映射这些布尔值占用1个字节的HDF5库),还有另一种方法吗?我的意思是我可以在结构中保证有1个字节的内容吗?

编辑

同样的问题也适用于int16值:取决于由于对齐原因而存在多少个值,最后结构的大小可能与预期的不同。在C#方面,我没有“看到” C ++结构,我只是按照C ++中结构的定义在非托管内存上写。这是一个非常简单的过程,但是如果我不得不考虑结构所占用的实际空间(通过猜测或测量),则每次修改结构时都会变得更加困难并且容易出错。

微病毒

这个答案是Hans Passant所说的补充。

使结构使用固定的包装尺寸可能是最容易的,因此您可以轻松地预测构件的布局。请记住,尽管这可能会影响性能。

此答案的其余部分特定于Microsoft Visual C ++,但是大多数编译器提供了它们自己的变体。

要开始使用,请查看此SO解答#pragma pack effect和MSDN http://msdn.microsoft.com/zh-cn/library/2e70t5y1.aspx

您经常使用的是一个成语,pragma pack(push, ...)后面是一个pragma pack(pop, ...)习惯用法,它仅影响两个杂注之间定义的结构的包装:

#pragma pack(push, 4)
struct someStructure
{
    char a;
    int b;
    ...
};
#pragma pack(pop)

这将使someStructure每个成员的4字节对齐方式具有可预见的打包。

编辑:从打包的MSDN页

成员的对齐将在n的倍数或成员大小的倍数(以较小者为准)的边界上。

因此,对于pack(4)achar将在1字节边界上对齐,ashort在2字节边界上对齐,而其余部分在4字节边界上对齐。

哪个值最佳取决于您的情况。您需要显式打包您打算访问的所有结构,以及可能是要访问的结构成员的所有结构。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章