首页 >后端开发 >C++ >如何在C#中高效地从字节数组中解析C/C数据结构?

如何在C#中高效地从字节数组中解析C/C数据结构?

Patricia Arquette
Patricia Arquette原创
2025-01-19 06:10:10855浏览

How to Efficiently Parse C/C   Data Structures from Byte Arrays in C#?

在 C# 字节数组中高效处理 C/C 数据结构

C# 和 C/C 之间的互操作通常需要数据结构转换。 本文介绍了以字节数组形式接收数据并将其转换为可用的 C# 结构体的常见场景。

字节数组数据结构的解析策略

C# 中成功从字节数组解析 C/C 结构的关键在于以下步骤:

  1. 匹配 C# 结构体定义: 创建一个镜像 C/C 结构体布局的 C# 结构体。 使用 [StructLayout][FieldOffset].

    等属性精确定义数据类型、大小和字段偏移量
  2. 内存固定:使用GCHandle来固定字节数组,防止垃圾收集在解析过程中重新定位它。

  3. 直接内存转换: 使用 Marshal.PtrToStructure 直接将固定内存地址转换为您定义的 C# 结构体。 与其他方法相比,这提供了卓越的性能。

  4. 内存释放: 至关重要的是,使用 handle.Free() 释放固定内存,以避免数据处理后发生内存泄漏。

说明性示例:C 到 C# 结构体转换

让我们考虑一个 C 结构体 (OldStuff) 及其等效的 C# 结构体 (NewStuff):

C 结构:

<code class="language-c++">typedef struct OldStuff {
    CHAR Name[8];
    UInt32 User;
    CHAR Location[8];
    UInt32 TimeStamp;
    UInt32 Sequence;
    CHAR Tracking[16];
    CHAR Filler[12];
} OldStuff;</code>

C# 结构:

<code class="language-csharp">[StructLayout(LayoutKind.Explicit, Size = 56, Pack = 1)]
public struct NewStuff
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    [FieldOffset(0)]
    public string Name;

    [MarshalAs(UnmanagedType.U4)]
    [FieldOffset(8)]
    public uint User;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    [FieldOffset(12)]
    public string Location;

    [MarshalAs(UnmanagedType.U4)]
    [FieldOffset(20)]
    public uint TimeStamp;

    [MarshalAs(UnmanagedType.U4)]
    [FieldOffset(24)]
    public uint Sequence;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    [FieldOffset(28)]
    public string Tracking;

    // Filler is omitted in C# as it's not needed for data access.
}</code>

以下 C# 方法演示了字节数组解析:

<code class="language-csharp">public NewStuff ByteArrayToNewStuff(byte[] bytes)
{
    GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    try
    {
        return (NewStuff)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(NewStuff));
    }
    finally
    {
        handle.Free();
    }
}</code>

性能优化

虽然BinaryReader提供了一种替代方案,但Marshal.PtrToStructure通常通过直接转换内存地址来提供卓越的性能,避免格式解释开销。 这种直接方法对于大型数据集特别有益。

通过采用这些技术,开发人员可以实现对 C# 字节数组中嵌入的 C/C 数据结构的高效且高性能的解析。

以上是如何在C#中高效地从字节数组中解析C/C数据结构?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn