PInvoke возвращает структуру с массивом двух измерений

У меня есть структура, которая определена в 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;
}

Как я могу получить возвращаемое значение этой функции, если я использую P/Invoke из приложения C #

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

Другие решения

Ответ короткий, но неутешительный: вам нужно преобразовать многомерный массив в одномерный.

Есть ответ, использующий AllocHGlobal: Передача многомерного массива из управляемого кода в неуправляемый код

Это решение делает то же самое, но в определении C # в вашем случае вы должны сделать data поле должно иметь тип IntPtr и в неуправляемом коде вы должны предполагать, что это одномерный массив.

Есть другое решение, использующее Marshal.UnsafeAddrOfPinnedArrayElement (MSDN а также Переполнение стека), но все равно предполагается, что вы используете одномерные массивы.

Лучшие варианты будут следовать, если вы расскажете, какую проблему вы пытаетесь решить. Это чистый возврат из одной очень важной функции и забыть об этом PInvoke или вы пытаетесь сделать постоянный двунаправленный маршаллинг?

1

По вопросам рекламы [email protected]