使用二维数组调用返回结构

PInvoke return struct with two dimensions array

本文关键字:返回 结构 调用 二维数组      更新时间:2023-10-16

我有在c ++ Win32 DLL中定义的结构,如下所示:

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

我不确定它是否有效,但从内存中: 将数据声明为 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;
}

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

使用 AllocHGlobal 有一个答案:将多维数组从托管代码传递到非托管代码

此解决方案执行类似操作,但在 C# 定义中,您必须使data字段为 IntPtr 类型,而在非托管代码中,您必须假定它是一个一维数组。

还有另一种使用Marshal.UnsafeAddrOfPinnedArrayElement的解决方案(MSDN 和 StackOverflow),但它仍然假设您使用的是一维数组。

如果您告诉您要解决的问题是什么,那么更好的选择就会随之而来。它是纯粹的返回一个非常重要的功能并忘记这个 PInvoke 还是您正在尝试进行持续的双向编组?