C#将结构数组复制到双精度数组

Wil*_*ert 2 c# value-type memcpy

[StructLayout(LayoutKind.Sequential)]
public struct Demo
{
    double X;
    double Y;
}


var data = new Demo[128];

FillWithMeaningfulValues(data);

double[] doubles;

Copy(data, out doubles); // ?
Run Code Online (Sandbox Code Playgroud)

如何将演示阵列复制到双精度数组中,而不必(...)通过每个元素?在C++中,我会使用memcpy,但在C#中我没有找到Marshal.Copy中我需要的东西.

void MethodIDoNotWantToUse(Demo[] demo, out double[] doubles)
{
    doubles = new double[demo.Length * 2];
    for(int i = 0, j = 0; i < demo.Length; ++i)
    {
        doubles[j++] = demo[i].X;
        doubles[j++] = demo[i].Y;
    }  
}

void MethodIWouldPreferToUse(Demo[] demo, out double[] doubles)
{
    doubles = new double[demo.Length * 2];
    memcopy(doubles, demo, demo.Length * 2 * sizeof(double));
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 6

由于结构体是 blittable 的,所以结构体的数组是 blittable 的。因此,您可以固定结构数组并使用Marshal.Copy.

void CopyDemoArrayToDoubleArray(Demo[] demo, out double[] doubles)
{
    doubles = new double[demo.Length * 2];
    GCHandle gch = GCHandle.Alloc(demo, GCHandleType.Pinned);
    try
    {
        IntPtr demoPtr = gch.AddrOfPinnedObject();
        Marshal.Copy(demoPtr, doubles, 0, doubles.Length);
    }
    finally
    {
        gch.Free();
    }
}
Run Code Online (Sandbox Code Playgroud)

您可能会根据for您想要避免的更简单的循环对此进行基准测试。for循环将完全充分地执行是合理的。


Sri*_*vel 5

你会做这样的事情.Marshal.Copy确实为您提供所需.

Demo[] array = new Demo[2];
array[0] = new Demo {X = 5.6, Y= 6.6};
array[1] = new Demo {X = 7.6, Y = 8.6};
GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
try
{
    IntPtr pointer = handle.AddrOfPinnedObject();
    double[] copy = new double[array.Length*2];//This length may be calculated
    Marshal.Copy(pointer, copy, 0, copy.Length);
}
finally
{
    if (handle.IsAllocated)
        handle.Free();
}
Run Code Online (Sandbox Code Playgroud)