我有一个byte[]对象,我正在使用它作为数据缓冲区。
我想把它“读”成一个基元/非基元结构的数组,而不在内存中复制byte[]数据。
目标应该类似于:
byte[] myBuffer;
//Buffer is populated
int[] asInts = PixieDust_ToInt(myBuffer);
MyStruct[] asMyStructs = PixieDust_ToMyStruct(myBuffer);这个是可能的吗?如果是这样的话,是怎么做的?
发布于 2019-11-19 22:55:22
有可能吗?实际上,是的!
从.NET Core2.1开始,MemoryMarshal允许我们对跨度执行此操作。如果您对span而不是数组感到满意,则选择yes。
var intSpan = MemoryMarshal.Cast<byte, int>(myByteArray.AsSpan());整数跨度将包含byteCount /4整数。
至于自定义结构...文档声称在转换的两端都需要一个“原始类型”。但是,您可以尝试使用ref struct,并看到这是实际的约束。如果它成功了,我也不会感到惊讶!
请注意,ref结构仍然具有很大的局限性,但对于我们正在讨论的那种重新解释类型转换来说,这种限制是有意义的。
编辑:哇,约束要宽松得多。它需要任何结构,而不是原语。它甚至不需要是一个ref struct。如果您的结构在其层次结构中的任何位置包含引用类型,则只会引发运行时检查。这事儿可以理解。因此,这应该适用于您的自定义结构,就像它适用于it一样。享受吧!
发布于 2016-10-18 21:51:03
您将无法执行此操作。要获得MyStruct[],您需要实际创建这种类型的数组,并复制数据。理论上,您可以创建自己的自定义类型作为集合,但实际上只是byte[]上的外观,在访问给定值时将字节复制到struct对象中,但如果您最终实际访问所有值,这最终将复制所有相同的数据,这可能会允许您将其推迟一点,如果您实际只使用少量值,这可能会很有帮助。
发布于 2016-10-18 22:51:59
这个类有一些函数,可以将从给定索引处开始的字节重新解释为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);https://stackoverflow.com/questions/40110062
复制相似问题