如何在不拷贝的情况下将结构体转换为字节数组?

3
[StructLayout(LayoutKind.Explicit)]
public struct struct1
{
    [FieldOffset(0)]
        public byte a;   // 1 byte
    [FieldOffset(1)]
        public int b;    // 4 bytes
    [FieldOffset(5)]
        public short c;  // 2 bytes
    [FieldOffset(7)]
        public byte buffer;
    [FieldOffset(18)]
        public byte[] shaHashResult;   // 20 bytes
}

void DoStuff()
{
   struct1 myTest = new struct1();
   myTest.shaHashResult =  sha256.ComputeHash(pkBytes);  // 20 bytes

   byte[] newParameter = myTest.ToArray() //<-- How do I convert a struct 
                                          //     to array without a copy?
}

如何将数组myTest转换为? 由于我的对象很大,我不想复制该数组(memcopy等)



3
如果你想避免复制,你可能想将其更改为一个“类”。 - SLaks
2
你分配的字节数组只是一个指针,它不是内联的。 - codekaizen
@codekaizen 提出了一个非常重要的观点。shaHashResult 数组中的字节不在结构体中,它们在堆中的某个地方。结构体只有对数组对象的引用。 - hatchet - done with SOverflow
这个方案永远行不通的原因在于ComputeHash的实现中有一个语句,它本质上是new Byte[20]。这将总是在GC堆上分配一个新数组,意味着需要执行一次复制。 - codekaizen
这里有一个类似的SO问题,讨论了在结构体中尝试内联数组的问题。http://stackoverflow.com/questions/690382/how-can-i-put-an-array-inside-a-struct-in-c - hatchet - done with SOverflow
显示剩余2条评论
1个回答

0
由于你有一个大数组,这确实是你能做到想要的唯一方法:
var myBigArray = new Byte[100000];

// ...

var offset = 0;
var hash = sha256.ComputeHash(pkBytes);
Buffer.BlockCopy(myBigArray, offset, hash, 0, hash.Length);

// if you are in a loop, do something like this
offset += hash.Length;

这段代码非常高效,即使在紧密的循环中,ComputeHash 的结果也会在快速的 Gen0 集合中收集,而 myBigArray 将位于大对象堆上,不会被移动或收集。运行时中的 Buffer.BlockCopy 是高度优化的,可以产生最快的复制速度,即使面对固定目标和使用展开指针复制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接