PInvoke返回带有两个维数组的结构

时间:2012-09-24 08:34:32

标签: c++ interop pinvoke marshalling managed

我有在 Win32 DLL中定义的struct,如下所示:

typedef struct matrix
{
  double** data;
  int m;
  int n;
} Matrix;

还有一个功能:

Matrix getMatrix(void);

Matrix getMatrix()
{
    Matrix mat;

    mat.m = 2;
    mat.n = 2;

    mat.data    = (double**)  malloc (sizeof(double*) * 4);

    mat.data[0] = (double* )  malloc (sizeof(double) * 2);
    mat.data[1] = (double* )  malloc (sizeof(double) * 2);

    mat.data [0][0]=1;
    mat.data [0][1]=2;
    mat.data [1][0]=3;
    mat.data [1][1]=4;

    return mat;
}

如何捕获此函数的返回值如果我在C#应用程序中使用P/Invoke

2 个答案:

答案 0 :(得分:4)

我不确定它是否有效,但是从内存中:将数据声明为IntPtr并使用它 :

static double[][] FromNative (IntPtr data, int m,int n)
{
   var matrix=new double[m][];

   for(int i=0;i<m;i++)
   {
       matrix[i]=new double[n];
       Marshal.Copy(Marshal.ReadIntPtr(data),matrix[i],0,n);
       data =(IntPtr)(data.ToInt64()+IntPtr.Size);
   }

   return matrix;
}

答案 1 :(得分:1)

答案很简短但令人失望:你必须将多维数组转换为单维数组。

有一个使用AllocHGlobal的答案:Pass multi - dimensional array from managed code to unmanaged code

此解决方案做了类似的事情,但在您的情况下,在C#定义中,您必须使data字段为IntPtr类型,而在非托管代码中,您必须假设它是一维数组。 / p>

使用Marshal.UnsafeAddrOfPinnedArrayElementMSDNStackOverflow)还有另一种解决方案,但它仍假设您使用的是一维数组。

如果你告诉你要解决的问题是什么,那么会有更好的选择。它是一个纯粹的回归 - 从一个非常重要的功能 - 忘记这个PInvoke还是你试图进行恒定的双向编组?