2012-09-24 21 views
3

我这是在的Win32 DLL中定义类似如下结构:与二维数组PInvoke的回报结构

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

+1

这看起来像C比C++多。 – juanchopanza

+0

我会认为'double **'转换为'double [] []'。不确定是否必须用属性修饰它才能让它正常工作。 –

+0

@lc。你需要手动编组 –

回答

3

我不知道是否可行,但是从内存:声明数据的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; 
} 
+0

'new double []'将位于托管内存中。而C#中的double数组是具有不同布局的对象。不幸的是,你的方法是行不通的。 –

+0

对不起,如果有人可以格式化我的答案,我的手机编辑器不会格式化它的权利。如果他想要double [,]而不是double [] []我可以编辑这个问题吗? – user629926

+0

它更好,但问题仍然是数组的“2D-ness”。你提出的曲折数组不会映射'**'指针。 –

1

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

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

这种解决方案类似的事情,但在你的情况下,C#的定义,你必须做出data场是IntPtr的类型和非托管代码中,你必须承担它是一个一维数组。

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

如果您告诉您正在尝试解决的问题是什么,那么会有更好的选项。它是一个纯粹的从一个非常重要的功能和遗忘这个PInvoke返回还是你试图做一个不断的双向编组?

+0

您当然不需要转换为单维 –