亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從字節數組中讀取C#中的C / C ++數據結構

從字節數組中讀取C#中的C / C ++數據結構

UYOU 2019-08-12 16:29:28
從字節數組中讀取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));
    }}


查看完整回答
反對 回復 2019-08-12
?
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();
    }}


查看完整回答
反對 回復 2019-08-12
?
LEATH

TA貢獻1936條經驗 獲得超7個贊

注意包裝問題。在示例中,您給出了所有字段都處于明顯的偏移量,因為一切都在4字節邊界上,但情況并非總是如此。默認情況下,Visual C ++打包為8字節邊界。


查看完整回答
反對 回復 2019-08-12
  • 3 回答
  • 0 關注
  • 522 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號