在C#中,我需要将T[]写入流中,最好不使用任何额外的缓冲区。我有一个动态代码,可以将T[](其中T是一个无对象结构)转换为void*并将其固定在内存中,这很好用。当流是文件时,我可以使用本机Windows API直接传递void *,但现在我需要写入一个接受byte[]的通用Stream对象。
问题:有人能建议一种hack方法来创建一个虚拟数组对象,它实际上没有任何堆分配,而是指向已经存在(并固定的)堆位置吗?
以下是我需要的伪代码:
问题:有人能建议一种hack方法来创建一个虚拟数组对象,它实际上没有任何堆分配,而是指向已经存在(并固定的)堆位置吗?
以下是我需要的伪代码:
void Write(Stream stream, T[] buffer)
{
fixed( void* ptr = &buffer ) // done with dynamic code generation
{
int typeSize = sizeof(T); // done as well
byte[] dummy = (byte[]) ptr; // <-- how do I create this fake array?
stream.Write( dummy, 0, buffer.Length*typeSize );
}
}
更新:
我在这篇文章中详细描述了如何使用fixed(void* ptr=&buffer)
。我可以创建一个byte[],将其固定在内存中,并从一个指针不安全地复制字节,然后将该数组发送到流中,但我希望避免不必要的额外分配和复制。
不可能吗?
经过进一步思考,byte[] 在堆上具有一些元数据,包括数组维度和元素类型。仅将T[]的引用(指针)作为byte[]传递可能行不通,因为块的元数据仍然是T[]的元数据。即使元数据的结构相同,T[]的长度也远小于byte[],因此任何由托管代码对byte[]的后续访问都会生成不正确的结果。
请求微软连接的功能
请投票支持此请求,希望微软能听取您的声音。
BinaryFormatter
,我会强烈反对它;-p - Marc Gravell