Я использую C ++ DLL в моем проекте C #. Использование pInvoke (Платформа Invoke).
Мой код C ++ возвращает двойное ***, а функция C # возвращает IntPtr.
У меня размеры матрицы с обеих сторон, они просто не постоянны.
На стороне C # у меня есть:
[DllImport("mylib.dll")]
public static extern IntPtr GetMatrix(int width, int height, int depth);
И на стороне C ++ у меня есть:
extern "C" {
__declspec(dllexport) double*** GetMatrix(int width, int height, int depth) {
// do stuff
return matrix;
}
}
Теперь мне нужно преобразовать этот IntPtr в двойной [,,], но я понятия не имею, как это сделать.
В основном мне нужен ответ на вопрос этот вопрос.
Я никогда не пробовал это с такими массивами, но это первое решение может сработать, и я уверен, что эта статья MSDN:
(Обратите внимание, это работает, только если вы можете изменить определение функции на стороне C #) В вашей функции C # измените IntPtr
параметр к double[,,]
параметр и добавьте к нему атрибут MarshalAs, аналогично тому, как это делается в вышеприведенной статье MSDN.
[DllImport("FooBar.dll")]
extern void Foo([MarshalAs(UnmanagedType.LPArray, SizeConst=**YOUR ARRAY SIZE HERE**)] double[,,] bar);
Это также предполагает, что у вас есть массив постоянного размера, и я не уверен, как именно это будет работать с трехмерным массивом, но если вы хотите исследовать этот тип решения дальше, вот полная документация для MarshalAsAttribute.
Другое решение очень похоже на противоположность этому другому вопросу. Вы бы инициализировали свой double[,,]
до нужного размера, затем начните заполнять строки Marshal.Copy
(эта перегрузка). Вы также можете маршалировать над одним двойником с той же функцией. Что-то вроде этого:
double[,,] arr = new double[25, 25, 200];
int il = arr.GetLength(0), jl = arr.GetLength(1), kl = arr.GetLength(2);
IntPtr values = DllFoo();
for (int i = 0; i < il; i++)
{
for (int j = 0; j < jl; j++)
{
for (int k = 0; k < kl; k++)
{
double[] temp = new double[1];
arr[i,j,k] = Marshal.Copy(values, temp, 1, k + j * jl + k * jl * kl);
}
}
}
Вы можете определенно выжать гораздо больше производительности из этого фрагмента, но он все равно должен работать.