首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用MarshalAs和StructLayout读取二进制数据

使用MarshalAs和StructLayout读取二进制数据
EN

Stack Overflow用户
提问于 2009-12-11 19:46:23
回答 4查看 1.4K关注 0票数 2

我被困在这个问题上了。

我正在读取一个二进制文件,它的格式如下:

代码语言:javascript
复制
Field name  Size in bytes     Example
-------------------------------------
Date        19                1998_12_22 PM 20:15
Serial      4                 0001

使用下面的结构和对this question的回答,我正在尝试读取文件。

代码语言:javascript
复制
[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不是正确的偏移量,对吗?

EN

回答 4

Stack Overflow用户

发布于 2009-12-11 19:56:59

数据(23字节)和结构大小(24字节)之间似乎存在大小问题。这正常吗?

更新: Pack=1属性应该保证内存对齐,但是googling在结构的字段对齐上给出了不同的响应。您可以做的是读取字节数组中的23个字节,然后使用Encoding类提取两个字符串:

代码语言:javascript
复制
byte[] array = ... // read 23 bytes
String s1 = Encoding.ASCII.GetString(array, 0, 19);
String s2 = Encoding.ASCII.GetString(array, 19, 4); 
票数 1
EN

Stack Overflow用户

发布于 2009-12-11 21:48:25

没有一个答案是我正在寻找的,但我自己通过定义下面的struct als找到了一种更好的方法。

代码语言:javascript
复制
[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。上面的方法运行良好。

无论如何,谢谢你们所有人!

票数 1
EN

Stack Overflow用户

发布于 2009-12-11 20:03:02

对于这个架构,20可能是正确的偏移量。编译器将用零填充以将结构成员放在偶数位置。确切的“偶数”取决于体系结构和编译器,但如果我没有弄错的话,在32位体系结构中它必须是4的倍数。

例如,下面的结构:

代码语言:javascript
复制
struct MyStruct
{
  char ch;  // Offset 0
            // 3 "invisible" bytes padding inserted by the compiler
  int i;    // Offset 4
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1887554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档