我有一个System.Array
值结构类型,如下所示:
public value struct Position
{
int timestamp;
float x;
float y;
}
Position[] positions = new Position[1000 * 1000];
使用值初始化数组后,如何在不串行化一个项目的情况下获取byte[]
内容?
在C ++ / CLI中,我将使用pin_ptr
来获取指向数组内容的指针,然后从那里复制数据。我可以在C#中做这样的事情吗?
编辑:我需要将原始数据写入磁盘,就好像它是一个C结构,没有任何序列化。
我将此问题标记为C#以获得更广泛的曝光率,但实际上我正在尝试从IronPython序列化数据,因此这意味着我无法使用任何unsafe
C#功能。
答案 0 :(得分:2)
也许这会有所帮助:
[Serializable()]
public struct Position
{
int timestamp;
float x;
float y;
}
static void Main(string[] args)
{
var positions = new Position[1000 * 1000];
GetBytes(positions);
}
private static byte[] GetBytes(object obj)
{
using (var memoryStream = new System.IO.MemoryStream())
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryFormatter.Serialize(memoryStream, obj);
return memoryStream.ToArray();
}
}
答案 1 :(得分:1)
我相信这相当于使用不安全的C#代码的C ++ / CLI pin_ptr:
public static unsafe byte[] GetBytes(Position[] positions)
{
byte[] result = new byte[positions.Length * Marshal.SizeOf(typeof(Position))];
fixed (Position* ptr = &positions[0])
{
Marshal.Copy((IntPtr)ptr, result, 0, result.Length);
}
return result;
}
答案 2 :(得分:1)
这是一种不需要不安全代码的方法:
[更新以删除for循环并一次执行副本]
private static byte[] StructureToByteArray(Position[] posArray)
{
if (posArray == null || posArray.Length == 0)
{
return new byte[0];
}
var lenOfObject = Marshal.SizeOf(typeof(Position));
var len = lenOfObject * posArray.Length;
var arr = new byte[len];
var handle = GCHandle.Alloc(posArray, GCHandleType.Pinned);
try
{
var ptr = handle.AddrOfPinnedObject();
Marshal.Copy(ptr, arr, 0, len);
}
finally
{
handle.Free();
}
return arr;
}