【问题标题】:PInvoke return struct with two dimensions array具有二维数组的 PInvoke 返回结构
【发布时间】:2012-09-24 08:34:32
【问题描述】:

我有一个在 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,如何捕获此函数的返回值

【问题讨论】:

  • 这看起来更像是 C 而不是 C++。
  • 我认为double** 转换为double[][]。不确定是否必须用属性装饰它才能使其正常工作。
  • @lc。您需要手动编组它
  • 您声明数据为double**,但实际上它是int**。解决这个问题,@user629926 的回答技术会让你回家。
  • 你第一个 malloc 是错误的。应该是mat.data = (int**) malloc (sizeof(int*) * mat.m),但最好是(int**) malloc(sizeof(*mat.data)*mat.m)

标签: c++ c++ interop pinvoke marshalling managed


【解决方案1】:

我不确定它是否有效,但来自内存:Declare data as IntPtr and use this :

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;
}

【讨论】:

  • 'new double[]' 将在托管内存中。 C# 中的双数组是具有不同布局的对象。不幸的是,你的方法行不通。
  • 对不起,如果有人可以格式化我的答案,我的移动编辑器将无法正确格式化。如果他想要 double[,] 而不是 double[][] 我可以编辑问题吗?
  • 比较好,但是问题还是出在数组的2D-ness上。您建议的之字形数组不会映射“**”指针。
  • 我只是假设双**他想要双数组的数组。
  • 免费是什么意思。如果您希望从 c# 中释放由 struct 分配的内存。您应该制作自己的免费例程,将其导出并从 c# 调用 lt。
【解决方案2】:

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

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

此解决方案做类似的事情,但在 C# 定义中,您必须将 data 字段设为 IntPtr 类型,并且在非托管代码中,您必须假定它是一维数组。

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

如果您说出您要解决的问题是什么,将会有更好的选择。它是纯粹从一个非常重要的功能返回并忘记这个 PInvoke 还是您尝试进行持续的双向编组?

【讨论】:

  • 你当然不需要转成一维
猜你喜欢
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 2020-12-01
  • 2011-06-22
相关资源
最近更新 更多