Передача аргумента 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);

С уважением

Другие вопросы по тегам