有人可以帮助我以这种方式将结构数组转换为字节数组吗?
我从这里开始的代码是:https://stackoverflow.com/a/3577227
这是关于将浮点值的数组强制转换为字节数组,然后使用一些肮脏的肮脏代码将其重新返回,而不进行任何复制。它在数组中包含大量项目的大型项目中具有巨大的使用价值,因此您可以通过写出原始字节直接将它们“解序列化”到文件中。对于基于Plain Old Data结构的类型,此方法之所以有效,是因为除了数据之外,别无他用。
去年,我成功地修改了此代码以使其可与任何struct类型一起使用,但我不幸地丢失了代码。有谁想弄清楚吗?我对此真的很感兴趣。
目标很简单:仅通过更改内部C#数组标头诱使它转换为其他数据类型,即可将结构数组转换为字节数组并再次返回。有可能。
问题在于弄清楚代码中的所有细节。瞥见它的全部功能并将其完美连接。联合可以帮助在任何一个指针上的相同存储器地址上进行写入。这里的所有内容都具有重要的功能,主要是通过反复试验和思考来掌握。
我正在获取的数组头数据可能是主要问题。如果我没记错的话,我会另辟way径。
此代码可以编译,但不能正确更改数组头:
public static unsafe class FastArraySerializer
{
[StructLayout(LayoutKind.Explicit)]
private struct Union
{
[FieldOffset(0)] public byte[] bytes;
[FieldOffset(0)] public dynamic data;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct ArrayHeader
{
public UIntPtr type;
public UIntPtr length;
}
private static UIntPtr arrayHeaderInfo<T>(T[] data)
{
var union = new Union {data = data};
fixed (void* pBytes = union.bytes)
{
return getHeader(pBytes)->type;
}
}
private static UIntPtr arrayHeaderInfo_byteArray()
{
fixed (void* pBytes = new byte[1])
{
return getHeader(pBytes)->type;
}
}
public static T[] toTypeArray<T>(this byte[] bytes) where T:struct
{
var byteArrayLength = bytes.Length;
var union = new Union {bytes = bytes};
fixed (void* pArray = union.bytes)
{
var pHeader = getHeader(pArray);
pHeader->type = arrayHeaderInfo(new T[0]);
var sizeOf = Marshal.SizeOf(new T());
pHeader->length = (UIntPtr)(byteArrayLength / sizeOf);
}
return (T[])union.data;
}
public static byte[] toByteArray<T>(this T[] data) where T:struct
{
var typeArrayLength = data.Length;
var union = new Union {data = data};
fixed(void* pArray = union.bytes)
{
var pHeader = getHeader(pArray);
pHeader->type = arrayHeaderInfo_byteArray();
var sizeOf = Marshal.SizeOf(new T());
pHeader->length = (UIntPtr)(typeArrayLength * sizeOf);
}
return union.bytes;
}
private static ArrayHeader* getHeader(void* pBytes)
{
return (ArrayHeader*)pBytes - 1;
}
}