我需要对几个嵌套结构进行复杂的封送处理,其中包含到其他结构的可变长度数组,因此我决定使用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] 删除。
我来说两句