从字节数组中读取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条经验 获得超5个赞
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条经验 获得超6个赞
注意包装问题。在示例中,您给出了所有字段都处于明显的偏移量,因为一切都在4字节边界上,但情况并非总是如此。默认情况下,Visual C ++打包为8字节边界。
- 3 回答
- 0 关注
- 470 浏览
添加回答
举报
0/150
提交
取消