我正在尝试创建一个包装器,将System.Numeric.Complex数组视为double数组,即将{{1,2},{3,4},{5,6},{7,8}
视为{1,2,3,4,5,6,7,8}
。我使用这些数组进行FFT,因此这种方式会更有效,因为避免复制和迭代大数组。但是我坚持使用一个奇怪的嵌合怪物:一个类似double[] {System.Numerics.Complex[4]
的双数组对象,而不是double[8]
!!那是什么?
我不是互操作专家,所以请原谅任何重要的错误;我读了一些相关的东西here和here,我想知道这些数组是否重叠。这段代码几乎可以工作,只是它返回了一半的值:
//using System.Runtime.InteropServices;
//using System.Numeric;
[StructLayout(LayoutKind.Explicit)]
public struct ComplexArray2serialWrapper
{
[FieldOffset(0)] private Complex[] ComplexArray;
[FieldOffset(0)] private double[] DoubleArray;
public ComplexArray2serialWrapper(Complex[] NewcomplexArray) : this() { ComplexArray = NewcomplexArray; }
public ComplexArray2serialWrapper(double[] NewSerialComplexArray) : this() { DoubleArray = NewSerialComplexArray; }
public static implicit operator double[] (ComplexArray2serialWrapper source) { return source.DoubleArray; }
}
public static void TestWrapper()
{
Complex[] cc = { new Complex(1, 2), new Complex(3, 4), new Complex(5, 6), new Complex(7, 8) };
double[] DoubleComplexChimeraMonster = new ComplexArray2serialWrapper(cc);
var parenttype = DoubleComplexChimeraMonster.GetType(); // result = System.Numerics.Complex[]
//!!! but in watch window type shown as= double[] {System.Numerics.Complex[4]}
var ChildrenType = DoubleComplexChimeraMonster[0].GetType(); //System.Double
//In Watch window, children types shown chimeric:
//{ (1, 2)} Double {System.Numerics.Complex}
//{ (3, 4)} Double {System.Numerics.Complex}
//{ (5, 6)} Double {System.Numerics.Complex}
//{ (7, 8)} Double {System.Numerics.Complex}
double i1 = DoubleComplexChimeraMonster[0]; //=1 (as expected)
double i2 = DoubleComplexChimeraMonster[1]; //=2 (as expected)
double i3 = DoubleComplexChimeraMonster[2]; //=3 (as expected)
double i4 = DoubleComplexChimeraMonster[3]; //=4 (as expected)
var l = DoubleComplexChimeraMonster.Length; //=4 (8 expected)
//So trying to get i5-i8 will throw an exception e.g.:
//DoubleComplexChimeraMonster(4) --> exception (5 expected)
}
答案 0 :(得分:1)
您希望数组只存储双精度数。但它们也存储数组长度和对类型描述符的引用。因此,重叠两种.NET类型的方法不起作用。 C#不是C。
DoubleComplexChimeraMonster
被静态输入为double[]
,但GetType()
检索运行时类型,恰好是Complex[]
。
同一内存位置的重叠值适用于原始值类型。但是System.Array
是一个类。
正如Marc Gravell在您提供的answer链接中所说,不安全的指针可能是最佳选择。