Delphi打包记录中正确的结构布局 [英] Proper struct layout from delphi packed record

查看:82
本文介绍了Delphi打包记录中正确的结构布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将delphi应用程序转换为C#.有很多打包的记录,根据我几周前问的类似问题,最好转换为类.但是,有人告诉我我需要将它们转换为结构,我可以使用一些帮助.我将使用BinaryReader从文件读取并将值分配给结构内部的字段.

I'm converting a delphi app to C#. There are a bunch of packed records, and according to a similar question I asked a few weeks ago, it would be better to convert to classes. However, I'm told I need to convert them to structs, and I could use some help. I'm going to be using a BinaryReader to read from a file and assign values to the fields inside of the structs.

*请注意,我正在读取的文件是使用Delphi和打包记录创建的.

*Note, the file I'm reading from was made using Delphi and packed records.

这是一个示例结构:

Delphi:

Testrec = packed record
    now: TDateTime;
    MinLat: longint;
    MinLong: longint;
    Firsttime: TDateTime;
    MinAlt: single;
    MinFirst: single;
    MinDepth: single;
    MinSpeed: single;
    MinBot: single;
    res3: single;
    res4: single;
    res5: single;
    res6: single;
    MaxLat: longint;
    MaxLong: longint;
    Lasttime: TDateTime;
    MaxAlt: single;
    MaxFirst: single;
    MaxDepth: single;
    MaxSpeed: single;
    MaxBot: single;
    res9: single;
    res10: single;
    res11: single;
    res12: single;
    DataFlags: longint;
    ReviewFlags: longint;
    res13: longint;
    FirstPost: longint;
end;

这是我的C#版本:

public struct Testrec
{
    double now;
    int MinLat;
    int MinLong;
    double Firsttime;
    float MinAlt;
    float MinFirst;
    float MinDepth;
    float MinSpeed;
    float MinBot;
    float res3;
    float res4;
    float res5;
    float res6;
    int MaxLat;
    int MaxLong;
    double Lasttime;
    float MaxAlt;
    float MaxFirst;
    float MaxDepth;
    float MaxSpeed;
    float MaxBot;
    float res9;
    float res10;
    float res11;
    float res12;
    int DataFlags;
    int ReviewFlags;
    int res13;
    int FirstPost;
 }

我需要做StructLayoutSizeCharSet吗?

以下是有关读取二进制文件的相关delphi代码:

Here's the relevant delphi code regarding the reading of the binary file:

Testrec Header;
HeaderSize = 128;

RampStream:=TFileStream.Create(FilePath,fmOpenReadWrite OR fmShareExclusive );

RampStream.Read(Header,HeaderSize);
StartTime:=Header.Firsttime;
EndTime:=Header.Lasttime;

这是我设置二进制阅读器的方式:

Here's how I set up my Binary Reader:

RampStream = new BinaryReader(new FileStream(RampName, FileMode.Open, FileAccess.ReadWrite, FileShare.None));

推荐答案

您需要指定顺序布局,并将pack值指定为1.

You need to specify sequential layout and a pack value of 1.

[StructLayout(LayoutKind.Sequential, Pack = 1)]

由于没有文本成员,因此无需指定CharSet.并且您应该让编译器计算结构的大小.现在,指定了此选项后,您将能够将整个记录读入内存,然后直接将其blit到此C#结构上.像这样:

Since there are not textual members, you need not specify CharSet. And you should let the compiler calculate the size of the struct. Now, having specified this you will be able to read the entire record into memory, and then blit it directly onto this C# struct. Like so:

Testrec ReadRecFromStream(Stream stream)
{
    byte[] buffer = new byte[Marshal.SizeOf(typeof(Testrec))];
    stream.Read(buffer, 0, buffer.Length);
    GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
    try
    {
        return (Testrec)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Testrec));
    }
    finally
    {
        handle.Free();
    }
}

但是,您说过要一次读取成员并分配给C#结构中的相应字段.在这种情况下,无需寻求等效的二进制布局,因为您将不会使用它.如果要一次读取一个成员,则不需要StructLayout属性.您无需声明任何未使用的成员.您可以在输入点将Delphi日期时间值转换为适当的C#数据类型,依此类推.

However, you said that you were going to read on member at a time and assign to the corresponding field in the C# struct. In that case there's no need to seek binary layout equivalence since you won't be making any use of that. If you are going read one member at a time then you do not need a StructLayout attribute. You don't need to declare any unused members. You can convert the Delphi date time values into the appropriate C# data types at the point of input and so on.

因此,您确实需要确定是否要寻找这些结构的二元布局等效项.

So, you do need to make up your mind as to whether or not you are going to seek binary layout equivalence of these structures.

这篇关于Delphi打包记录中正确的结构布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆