ホームページ >バックエンド開発 >C++ >C# でバイト配列から C/C データ構造を効率的に解析するにはどうすればよいですか?

C# でバイト配列から C/C データ構造を効率的に解析するにはどうすればよいですか?

Patricia Arquette
Patricia Arquetteオリジナル
2025-01-19 06:10:10890ブラウズ

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。