使用C#中的PtrToStructure进行二进制文件反序列化

3

我正在尝试逆向工程我们公司的一堆遗留二进制数据,以便将其移动到更耐用的格式中。我们用来创建这些数据的应用程序已不再受支持。

我已经发现可以用一系列结构来描述这些数据,并且已经能够使用Marshal.PtrToStructure将它们编组到托管环境中,除了一个文件。

下面是我正在尝试解析的结构的示例。原始数据都是连续的,我正在尝试在一步中反序列化。

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DrillTPD
{
    public short Header;
    public short Header2;
    public short Header3;
    public short RecordCount;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 999)]
    public TPDHeader[] Templates;
} 
[StructLayout(LayoutKind.Sequential, Pack = 1, Size=18)]
struct TPDHeader
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
    public string TemplateName;
    public int TPDIndex;
}
是从文件开头算起的字节偏移量。我该如何添加一个属性以正确反序列化这些数据?
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 76)]
struct TPDParent
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
    public string TemplateName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)]
    public string Description;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
    public string Field;
    public double Width;
    public double Length;
    public double Thickness;
    public short WL;
    public short XY;
    public short Origin;
    public short Features;
    [MarshalAs(UnmanagedType.ByValArray)]
    public TPDDetail[] Details;
}
[StructLayout(LayoutKind.Sequential, Pack=1, Size=350)]
struct TPDDetail
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 350)]
    public string Text;
}

TPDParent 中的 TPDDetail 数组是由结构中的 Features 定义的。如果没有任何特征,则 TPDParent 之后不会出现 TPDDetail 数据。

我应该如何动态地让反序列化程序知道 TPDDetail 数组的大小?

这些数据的伪 XML 结构理想情况下应如下所示:

<DrillTPD>
    <TPDHeader>
        <TPDParent>
            <TPDDetail/>
            <TPDDetail/>
            <TPDDetail/>
        </TPDParent>
    </TPDHeader>
    <TPDHeader>
        .....
    </TPDHeader>
</DrillTPD>

最后补充一点:我只在.NET语言方面工作过,但我正在尝试了解非托管部分。感谢您简化回答的方式。:)

2个回答

0
尝试创建一个简单的结构层次实例,然后将其作为字节持久化到文件中。然后,您可以使用十六进制编辑器将输出与预期输出进行比较。差异将突出显示它未按照您的期望工作的地方。
否则,您正在尝试创建结构的完美定义,它将拒绝工作,直到完美实现,并且对于您所拥有的相当复杂的设置而言,这将是难以实现的。

0
从我的角度来看,如果您有两个类的话会更干净——一个输入类具有未管理的数据,第二个只有受管理的数据,它具有以输入类为参数的构造函数,并相应地标记为序列化——如果所有数据都受管理,则数组大小将由框架内部管理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接