從字節數組中讀取C#中的C / C ++數據結構從byte []數組填充C#結構的最佳方法是什么,其中數據來自C / C ++結構?C結構看起來像這樣(我的C很生銹):typedef OldStuff {
CHAR Name[8];
UInt32 User;
CHAR Location[8];
UInt32 TimeStamp;
UInt32 Sequence;
CHAR Tracking[16];
CHAR Filler[12];}并填寫這樣的東西:[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;}什么是復制OldStuff到的最佳方式NewStuff,如果OldStuff作為byte []數組傳遞?我現在正在做類似以下的事情,但感覺有點笨重。GCHandle handle;NewStuff MyStuff;int BufferSize = Marshal.SizeOf(typeof(NewStuff));byte[] buff = new byte[BufferSize];Array.Copy(SomeByteArray, 0, buff, 0, BufferSize);handle = GCHandle.Alloc(buff, GCHandleType.Pinned);MyStuff = (NewStuff)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(NewStuff));handle.Free();有沒有更好的方法來實現這一目標?使用BinaryReader該類可以提供超過內存和使用的任何性能提升Marshal.PtrStructure嗎?
3 回答

泛舟湖上清波郎朗
TA貢獻1818條經驗 獲得超3個贊
從我在該上下文中看到的內容,您不需要復制SomeByteArray
到緩沖區中。您只需要從中獲取句柄SomeByteArray
,固定它,IntPtr
使用PtrToStructure
然后釋放來復制數據。無需復印件。
那將是:
NewStuff ByteArrayToNewStuff(byte[] bytes){ GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { NewStuff stuff = (NewStuff)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(NewStuff)); } finally { handle.Free(); } return stuff;}
通用版本:
T ByteArrayToStructure<T>(byte[] bytes) where T: struct { T stuff; GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); } finally { handle.Free(); } return stuff;}
更簡單的版本(需要unsafe
切換):
unsafe T ByteArrayToStructure<T>(byte[] bytes) where T : struct{ fixed (byte* ptr = &bytes[0]) { return (T)Marshal.PtrToStructure((IntPtr)ptr, typeof(T)); }}

ibeautiful
TA貢獻1993條經驗 獲得超6個贊
public static T ByteArrayToStructure<T>(byte[] bytes) where T : struct{ var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { return (T) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); } finally { handle.Free(); }}

LEATH
TA貢獻1936條經驗 獲得超7個贊
注意包裝問題。在示例中,您給出了所有字段都處于明顯的偏移量,因為一切都在4字節邊界上,但情況并非總是如此。默認情況下,Visual C ++打包為8字節邊界。
- 3 回答
- 0 關注
- 522 瀏覽
添加回答
舉報
0/150
提交
取消