我被困在这个问题上了。
我正在读取一个二进制文件,它的格式如下:
Field name Size in bytes Example
-------------------------------------
Date 19 1998_12_22 PM 20:15
Serial 4 0001使用下面的结构和对this question的回答,我正在尝试读取文件。
[StructLayout(LayoutKind.Explicit, Size=23, Pack = 1)]
struct MeasurementStruct
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
[FieldOffset(0)]
public string Date;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
[FieldOffset(19)]
public string Serial;
}然而,当实例化包含此结构的类时,我在FieldOffset 19处得到一个错误。不幸的是,此错误是荷兰语,但它大致翻译为“无法加载MeasurementStruct,因为off 19处的字段没有很好地对齐(字段可能重叠)”。
我发现将FieldOffset19更改为FieldOffset20会使错误消失。然而,在我的例子中,20不是正确的偏移量,对吗?
发布于 2009-12-11 19:56:59
数据(23字节)和结构大小(24字节)之间似乎存在大小问题。这正常吗?
更新: Pack=1属性应该保证内存对齐,但是googling在结构的字段对齐上给出了不同的响应。您可以做的是读取字节数组中的23个字节,然后使用Encoding类提取两个字符串:
byte[] array = ... // read 23 bytes
String s1 = Encoding.ASCII.GetString(array, 0, 19);
String s2 = Encoding.ASCII.GetString(array, 19, 4); 发布于 2009-12-11 21:48:25
没有一个答案是我正在寻找的,但我自己通过定义下面的struct als找到了一种更好的方法。
[StructLayout(LayoutKind.Sequential, Size = MeasurementStructSize, Pack = 1)]
struct MeasurementStruct
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
public string Date;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string SerialNumber;
}我把LayoutKind改成了顺序。在这种情况下,Pack字段实际上是有意义的,我不需要添加FieldOffsets。上面的方法运行良好。
无论如何,谢谢你们所有人!
发布于 2009-12-11 20:03:02
对于这个架构,20可能是正确的偏移量。编译器将用零填充以将结构成员放在偶数位置。确切的“偶数”取决于体系结构和编译器,但如果我没有弄错的话,在32位体系结构中它必须是4的倍数。
例如,下面的结构:
struct MyStruct
{
char ch; // Offset 0
// 3 "invisible" bytes padding inserted by the compiler
int i; // Offset 4
}https://stackoverflow.com/questions/1887554
复制相似问题