如何在没有副本的情况下将结构转换为字节数组?

Posted

技术标签:

【中文标题】如何在没有副本的情况下将结构转换为字节数组?【英文标题】:How do I convert a struct to a byte array without a copy? 【发布时间】:2012-12-17 22:34:20 【问题描述】:
[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 等)

【问题讨论】:

@SLaks 我发现了这个但没有推论:System.Runtime.InteropServices.Marshal.StructureToPtr 如果您想避免复制,您可能需要将其更改为class 您分配的字节数组只是一个指针。它不是内联的。 @codekaizen 有一个非常重要的观点。 shaHashResult 数组中的字节不在结构中。它们在堆中的某个地方。该结构只有对数组对象的引用。 叹息......当我想出使用 stuct 和/或 Marshal 时,我以为我走在了一个很好的轨道上 【参考方案1】:

由于您有一个大数组,这确实是您能够做您想做的事情的唯一方法:

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 在运行时进行了高度优化,即使在固定目标并使用展开的指针副本时,也能产生您可能实现的最快副本。

【讨论】:

以上是关于如何在没有副本的情况下将结构转换为字节数组?的主要内容,如果未能解决你的问题,请参考以下文章

将 char 数组转换为字节数组并再次返回

在 C# 中有效地将字符串转换为字节数组(不使用编码)[重复]

以编程方式将资源加载为字节数组

如何在 Parcel 的帮助下将 Parcelable 编组和解组为字节数组?

如何在 C# 中将结构转换为字节数组?

如何将字节数组转换为位图实例 (.NET)?