IntPtr到三维数组

时间:2015-07-18 23:32:46

标签: c# c++ arrays pinvoke intptr

我正在使用C ++ dll进入我的C#项目。使用pInvoke(平台调用)。

我的C ++代码返回一个double ***,C#函数返回一个IntPtr。

我在两边都有矩阵的尺寸,它们不是常数。

在C#方面,我有:

[DllImport("mylib.dll")]
public static extern IntPtr GetMatrix(int width, int height, int depth);

在C ++方面,我有:

extern "C" {
    __declspec(dllexport) double*** GetMatrix(int width, int height, int depth) {
        // do stuff
        return matrix;
    }
}

现在我需要将此IntPtr转换为double [,,],但是,我不知道该怎么做。

基本上,我需要对this question的答案。

1 个答案:

答案 0 :(得分:0)

我从来没有尝试使用这些类型的阵列,但是这个第一个解决方案可能有用,我会this MSDN article相信:

(注意这只适用于您可以更改C#端的功能定义)在C#函数中,将IntPtr参数更改为double[,,]参数并将此MarshalAs属性添加到其中,类似以上MSDN文章是如何做到的。

[DllImport("FooBar.dll")]
extern void Foo([MarshalAs(UnmanagedType.LPArray, SizeConst=**YOUR ARRAY SIZE HERE**)] double[,,] bar);

这也假设您有一个恒定大小的数组,并且我不确定这将如何与3d数组完全一致,但如果您想进一步调查此类解决方案,请在此处#39;是MarshalAsAttribute的完整文档。

另一个解决方案非常类似于其他问题的反面。您可以将double[,,]初始化为所需的大小,然后使用Marshal.Copythis overload)开始填充行。您也可以使用相同的功能编组一个双精度。像这样:

double[,,] arr = new double[25, 25, 200];
int il = arr.GetLength(0), jl = arr.GetLength(1), kl = arr.GetLength(2);

IntPtr values = DllFoo();

for (int i = 0; i < il; i++)
{
    for (int j = 0; j < jl; j++)
    {
        for (int k = 0; k < kl; k++)
        {
            double[] temp = new double[1];
            arr[i,j,k] = Marshal.Copy(values, temp, 1, k + j * jl + k * jl * kl);
        }
    }    
}

你绝对可以从该片段中获得更多性能,但它仍然可以正常工作。