其实C#中使用指针直接操作也可以实现,送上两个自己写的指针操作结构体转换的函数,使用泛型指定强类型,实现的效果和Marshal.Copy一样。 public static unsafe byte[] GetBytes<T>(object obj) { byte[] arr = new byte[Marshal.SizeOf(obj)]; GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned); void* pVer = handle.AddrOfPinnedObject().ToPointer(); fixed (byte* parr = arr) { *parr = *(byte*)pVer; } handle.Free(); return arr; } public static unsafe T GetObject<T>(byte[] bytes) where T : new() { T rect = new T(); GCHandle handle = GCHandle.Alloc(rect, GCHandleType.Pinned); void* pVer = handle.AddrOfPinnedObject().ToPointer(); fixed (byte* b = bytes) { *(byte*)pVer = *b; } return rect; }
ls的动作太敏捷了,剩下来只能jf
第二个函数改一下,漏写了“handle.Free();”,完整的如下 public static unsafe T GetObject<T>(byte[] bytes) where T : new() { T rect = new T(); GCHandle handle = GCHandle.Alloc(rect, GCHandleType.Pinned); void* pVer = handle.AddrOfPinnedObject().ToPointer(); fixed (byte* b = bytes) { *(byte*)pVer = *b; } handle.Free(); return rect; }
还有在struct中如何定义一个固定长度的数组? 就像C++的 struct T { char b[20]; int c; };
搜索了一下,似乎没有很优雅/直接的方法定义固定长度数组,在struct中
struct T { public T(int i) { b = new Char[i]; c = 0; } public Char[] b; public int c; };
这样: struct T { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] char[] b; int c; }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] 的char[] b 是无法直接使用的,用的时候还要new, 不等于 struct T { char b[20]; int c; }; 等于 struct T { char× b; int c; };
public static object BytesToStruct(byte[] bytes, Type strcutType)
{
int size = Marshal.SizeOf(strcutType);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(bytes, 0, buffer, size);
return Marshal.PtrToStructure(buffer, strcutType);
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
{
byte[] arr = new byte[Marshal.SizeOf(obj)]; GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
void* pVer = handle.AddrOfPinnedObject().ToPointer(); fixed (byte* parr = arr)
{
*parr = *(byte*)pVer;
} handle.Free();
return arr;
} public static unsafe T GetObject<T>(byte[] bytes) where T : new()
{
T rect = new T();
GCHandle handle = GCHandle.Alloc(rect, GCHandleType.Pinned);
void* pVer = handle.AddrOfPinnedObject().ToPointer(); fixed (byte* b = bytes)
{
*(byte*)pVer = *b;
}
return rect;
}
{
T rect = new T();
GCHandle handle = GCHandle.Alloc(rect, GCHandleType.Pinned);
void* pVer = handle.AddrOfPinnedObject().ToPointer(); fixed (byte* b = bytes)
{
*(byte*)pVer = *b;
}
handle.Free();
return rect;
}
就像C++的
struct T
{
char b[20];
int c;
};
{
public T(int i)
{
b = new Char[i];
c = 0;
} public Char[] b;
public int c;
};
struct T
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
char[] b;
int c;
}
的char[] b 是无法直接使用的,用的时候还要new,
不等于
struct T
{
char b[20];
int c;
};
等于
struct T
{
char× b;
int c;
};