2016-11-15 5 views
1

Я пытаюсь прочитать массив, созданный путем выведения функции dll из C#. Когда я распечатываю содержимое массива, на самом деле он заполнен барахлом.Каков правильный способ маршалирования const float **?

Я подозреваю, что это происходит из-за неправильной сортировки const float** до out IntPtr. Как вы должным образом маршалируете const float**?

DLL C++ интерфейс

int Foo(void *objPtr, uint64_t *resultLen, const float **result); 

DLL Импорт Заявление

[DllImport("foo.dll", CharSet = CharSet.Auto)] 
public static extern int Foo(IntPtr objPtr, out ulong resultLen, out IntPtr result); 

телефонный код

IntPtr objPtr = getObj(); 
IntPtr result; 
ulong resultLen; 
int output = Foo(objPtr, out resultLen, out result); 
+0

показан пример с ++ код, который вызывает функцию –

+0

вы можете рассмотреть возможность использования C++/CLI вместо P/Invoke –

ответ

3

Потому что нет возможности сообщить маршаллеру размер массива раньше времени, вам придется скопировать массив вручную. Таким образом, out IntPtr верен.

Обратите внимание, что у будет проблема с очень большими массивами. См. https://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx и How to get around Marshal.Copy (32bit) length limit?. Этот фрагмент будет использовать int в качестве результирующей длины массива. Вам нужно будет выяснить, что делать в вашем конкретном случае.

Также обратите внимание, что ваша DLL должна нести ответственность за освобождение выделенной памяти. См. Release unmanaged memory from managed C# with pointer of it.

IntPtr objPtr = getObj(); 
IntPtr result; 
int resultLen; 

// call your external function 
int output = Foo(objPtr, out resultLen, out result); 

// create an array to hold the output data 
float[] array = new float[resultLen]; 

// copy the data 
Marshal.Copy(result, array, 0, resultLen); 

// since the memory was allocated by the DLL only it knows how to free it 
// so call the free function exported by the DLL 
FreeBufferAfterFoo(result); 
+0

Спасибо за ответ. Поскольку вы говорите, что 'out IntPtr' является правильным, и поскольку у меня есть эквивалент вашего дополнительного кода в моем личном коде, кажется, причина того, что в моем массиве есть мусор, должна быть не связана с тем, как я сортировал' const float ** '. Я поддержал ваш ответ, поскольку он был очень информативным, хотя моя проблема еще не решена. Если на какое-то время не будет другого ответа, у меня может быть другое предложение, я отредактирую вопрос только о сортировке 'const float **', и я приму ваш ответ. Еще раз спасибо :) – cycloidistic

 Смежные вопросы

  • Нет связанных вопросов^_^