У меня есть структура, которая определена в 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;
}
Как я могу получить возвращаемое значение этой функции, если я использую P/Invoke
из приложения C #
Я не уверен, что это работает, но из памяти: объявите данные как 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 а также Переполнение стека), но все равно предполагается, что вы используете одномерные массивы.
Лучшие варианты будут следовать, если вы расскажете, какую проблему вы пытаетесь решить. Это чистый возврат из одной очень важной функции и забыть об этом PInvoke или вы пытаетесь сделать постоянный двунаправленный маршаллинг?