Передача аргумента char* в функцию C++ DLL из приложения C#
Я пытаюсь использовать функцию DLL, объявленную как void Process(char* data)
из C#.
DLL предоставляет различные функции для управления OculusRift. Предполагается, что эта функция отображает в Oculus изображение данных и используется другим полнофункциональным приложением.
В моем коде я генерирую byte [] из растрового изображения, затем преобразовываю его в другие вещи (char[], добавляем StringBuilder,...), чтобы передать его Process
функция.
Я загружаю эту функцию процесса из DLL через LoadLibrary
(загрузить DLL) + GetProcAdress
(для доступа к функции). Я не могу использовать DLLImport
потому что я хочу быть как можно ближе к тому, как интерфейс другого приложения (написанного на C++) работает с DLL.
Я пытался с помощью [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void Process([MarshalAs(UnmanagedType.LPStr)]StringBuilder data);
или просто [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void Process(StringBuilder data);
(Я прочитал передачу строки /StringBuilder мог бы добиться цели, потому что он по умолчанию маршалируется как char*). В результате у меня была полная строка, переданная в качестве аргумента DLL, а не char *.
Я также пытался передать IntPtr в качестве аргумента, используя Marshal Copy и
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void Process(IntPtr data);
,
В результате у меня было исключение нарушения доступа к памяти.
Затем я пробовал разные вещи, используя небезопасный код, например, реализуя весь процесс создания данных из другого приложения (для моих целей мне нужна только упрощенная версия) или создавая данные как я хочу в char[], а затем копировал этот char[] на символ *, который я передал
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private unsafe delegate void Process(char* data);
Это привело к исключениям переполнения стека из stackalloc и к исключению нарушения доступа к памяти.
На данный момент, я думаю, что я что-то упустил и нуждаюсь в вашей помощи. Я не знаю, есть ли какая-то блокировка, вызывающая ошибку исключения памяти (я убедился, что изображение имеет правильный размер), я не знаю, правильно ли я неправильно понял процесс маршалинга и т. Д.
Надеюсь, я достаточно ясно изложил свою проблему.
1 ответ
В C char используется для представления байтов, потому что в C тип байта не существует. Или просто равен типу символа.
Итак, чтобы отобразить из C#:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void Process([MarshalAs(UnmanagedType.LPArray)]byte[] data);
или же
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void Process(byte[] data);
С уважением