猿问

从字节数组中读取C#中的C / C ++数据结构

从字节数组中读取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吗?


UYOU
浏览 472回答 3
3回答

泛舟湖上清波郎朗

从我在该上下文中看到的内容,您不需要复制SomeByteArray到缓冲区中。您只需要从中获取句柄SomeByteArray,固定它,IntPtr使用PtrToStructure然后释放来复制数据。无需复印件。那将是:NewStuff&nbsp;ByteArrayToNewStuff(byte[]&nbsp;bytes){ &nbsp;&nbsp;&nbsp;&nbsp;GCHandle&nbsp;handle&nbsp;=&nbsp;GCHandle.Alloc(bytes,&nbsp;GCHandleType.Pinned); &nbsp;&nbsp;&nbsp;&nbsp;try &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NewStuff&nbsp;stuff&nbsp;=&nbsp;(NewStuff)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),&nbsp;typeof(NewStuff)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;finally &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handle.Free(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;stuff;}通用版本:T&nbsp;ByteArrayToStructure<T>(byte[]&nbsp;bytes)&nbsp;where&nbsp;T:&nbsp;struct&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;stuff; &nbsp;&nbsp;&nbsp;&nbsp;GCHandle&nbsp;handle&nbsp;=&nbsp;GCHandle.Alloc(bytes,&nbsp;GCHandleType.Pinned); &nbsp;&nbsp;&nbsp;&nbsp;try &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stuff&nbsp;=&nbsp;(T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),&nbsp;typeof(T)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;finally &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handle.Free(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;stuff;}更简单的版本(需要unsafe切换):unsafe&nbsp;T&nbsp;ByteArrayToStructure<T>(byte[]&nbsp;bytes)&nbsp;where&nbsp;T&nbsp;:&nbsp;struct{ &nbsp;&nbsp;&nbsp;&nbsp;fixed&nbsp;(byte*&nbsp;ptr&nbsp;=&nbsp;&bytes[0]) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(T)Marshal.PtrToStructure((IntPtr)ptr,&nbsp;typeof(T)); &nbsp;&nbsp;&nbsp;&nbsp;}}

ibeautiful

public&nbsp;static&nbsp;T&nbsp;ByteArrayToStructure<T>(byte[]&nbsp;bytes)&nbsp;where&nbsp;T&nbsp;:&nbsp;struct{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;handle&nbsp;=&nbsp;GCHandle.Alloc(bytes,&nbsp;GCHandleType.Pinned); &nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(T)&nbsp;Marshal.PtrToStructure(handle.AddrOfPinnedObject(),&nbsp;typeof(T)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;finally&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handle.Free(); &nbsp;&nbsp;&nbsp;&nbsp;}}

LEATH

注意包装问题。在示例中,您给出了所有字段都处于明显的偏移量,因为一切都在4字节边界上,但情况并非总是如此。默认情况下,Visual C ++打包为8字节边界。
随时随地看视频慕课网APP
我要回答