我有一个byte []对象,我将其用作数据缓冲区。
我希望将它“读取”为原始/非原始结构的数组,而不会复制内存中的byte []数据。
目标如下:
byte[] myBuffer;
//Buffer is populated
int[] asInts = PixieDust_ToInt(myBuffer);
MyStruct[] asMyStructs = PixieDust_ToMyStruct(myBuffer);
这可能吗?如果是这样,怎么样?
答案 0 :(得分:1)
你将无法做到这一点。要拥有MyStruct[]
,您需要实际创建此类型的数组并复制数据。理论上,您可以创建自己的自定义类型作为集合,但实际上只是byte[]
上的一个外观,在访问给定值时将字节复制到struct
对象中,但如果你最终实际访问了所有的值,最终会最终复制所有相同的数据,它可能会让你推迟一点,如果你只实际使用少量的值可能会有所帮助
答案 1 :(得分:1)
有可能吗?实际上,是的!
自.NET Core 2.1开始,MemoryMarshal
使我们可以跨度执行此操作。如果您对跨度而不是数组感到满意,那么可以。
var intSpan = MemoryMarshal.Cast<byte, int>(myByteArray.AsSpan());
int跨度将包含byteCount / 4个整数。
关于自定义结构...文档声称转换的两面都需要“原始类型”。但是,您可以尝试使用ref struct
并看到这是 actual 约束。如果有效的话,我不会感到惊讶!
请注意,引用结构仍然非常受限制,但是这种限制对于我们正在谈论的重新解释类型转换是有意义的。
编辑:哇,约束要严格得多。它需要任何结构,而不是基元。它甚至不必是ref struct
。如果您的结构在其层次结构中的任何位置包含引用类型,则只会抛出 runtime 检查。那讲得通。因此,这应该适用于您的自定义结构以及适用于int的结构。享受吧!
答案 2 :(得分:0)
为了将byte []转换为其他基本类型,您将获得的最接近的是
Byte[] b = GetByteArray();
using(BinaryReader r = new BinaryReader(new MemoryStream(b)))
{
r.ReadInt32();
r.ReadDouble();
r.Read...();
}
然而,没有简单的方法将byte []转换为任何类型的对象[]
答案 3 :(得分:0)
此类具有将从给定索引开始的字节重新解释为Int32,Int64,Double,Boolean等的函数,并从这些类型返回到字节序列。
示例:
int32 x = 0x12345678;
var xBytes = BitConverter.GetBytes(x);
// bytes is a byte array with length 4: 0x78; 0x56; 0x34; 0x12
var backToInt32 = BitConverter.ToInt32(xBytes, 0);
或者,如果您的数组包含混合数据:
double d = 3.1415;
int16 n = 42;
Bool b = true;
Uint64 u = 0xFEDCBA9876543210;
// to array of bytes:
var dBytes = BitConverter.GetBytes(d);
var nBytes = BitConverter.GetBytes(n);
var bBytes = BitConverter.GetBytes(b);
var uBytes = BitConterter.GetBytes(u);
Byte[] myBytes = dBytes.Concat(nBytes).Concat(bBytes).Concat(uBytes).ToArray();
// startIndexes in myBytes:
int startIndexD = 0;
int startIndexN = dBytes.Count();
int startIndexB = startIndexN + nBytes.Count();
int startIndexU = startIndexB + bBytes.Count();
// back to original elements
double dRestored = Bitconverter.ToDouble(myBytes, startIndexD);
int16 nRestored = BitConverter.ToInt16(myBytes, startIndexN);
bool bRestored = BitConverter.ToBool(myBytes, startIndexB);
Uint64 uRestored = BitConverter.ToUint64(myBytes, startIndexU);