Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Menghuraikan Struktur Data C/C dengan Cekap daripada Tatasusunan Byte dalam C#?
Mengendalikan Struktur Data C/C dengan Cekap dalam Tatasusunan Bait C#
Saling kendali antara C# dan C/C selalunya memerlukan penukaran struktur data. Artikel ini menangani senario biasa menerima data sebagai tatasusunan bait dan menukarnya menjadi struct C# yang boleh digunakan.
Strategi Penghuraian untuk Struktur Data Tatasusunan Bait
Kunci untuk berjaya menghuraikan struktur C/C daripada tatasusunan bait dalam C# terletak pada langkah-langkah ini:
Padanan Definisi Struktur C#: Cipta struktur C# yang mencerminkan reka letak struktur C/C. Tentukan jenis data, saiz dan ofset medan dengan tepat menggunakan atribut seperti [StructLayout]
dan [FieldOffset]
.
Semat Memori: Guna GCHandle
untuk menyemat tatasusunan bait, menghalang kutipan sampah daripada memindahkannya semasa proses penghuraian.
Penghantaran Memori Terus: Gunakan Marshal.PtrToStructure
untuk menghantar terus alamat memori yang disematkan ke struct C# yang anda tentukan. Ini menawarkan prestasi unggul berbanding kaedah alternatif.
Keluaran Memori: Yang penting, lepaskan memori yang disematkan menggunakan handle.Free()
untuk mengelakkan kebocoran memori sebaik sahaja data diproses.
Contoh Ilustrasi: Penukaran Struktur C kepada C#
Mari kita pertimbangkan struct C (OldStuff
) dan struct C# yang setara (NewStuff
):
Struktur 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>
Struktur 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>
Kaedah C# berikut menunjukkan penghuraian tatasusunan bait:
<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>
Pengoptimuman Prestasi
Walaupun BinaryReader
menyediakan alternatif, Marshal.PtrToStructure
secara amnya menawarkan prestasi unggul dengan menghantar terus alamat memori, mengelakkan tafsiran format overhed. Pendekatan langsung ini amat berfaedah untuk set data yang besar.
Dengan menggunakan teknik ini, pembangun boleh mencapai penghuraian yang cekap dan berprestasi bagi struktur data C/C yang dibenamkan dalam tatasusunan bait C#.
Atas ialah kandungan terperinci Bagaimana untuk Menghuraikan Struktur Data C/C dengan Cekap daripada Tatasusunan Byte dalam C#?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!