Передать указатель функции из C++ для вызова из C# - Аргументы функций включают в себя широкую строку символов (LPCWSTR)

Я пишу библиотеку C# для использования в собственных приложениях C++. Я использую C++/CLI в качестве механизма взаимодействия.

Мне требуется передать функцию обратного вызова из C++ в C# (используя C++/CLI в качестве промежуточного уровня). Библиотека C# должна вызывать функцию C++ с завершенной нулем строкой широких символов; то есть прототип функции обратного вызова

Func(LPCWSTR pszString);

Есть и другие параметры, но они несущественны для этого обсуждения.

Я искал net и нашел метод Marshal.GetDelegateForFunctionPointer, который я могу использовать. Проблема в том, что он преобразует System.String из C# в char *, а не в wchar_t *, который я ищу.

Кроме того, каков наилучший метод для достижения этого примера кода, включая часть C++/CLI, если это возможно. C++/CLI DLL зависит от C# DLL. Метод должен вызываться синхронно.

2 ответа

GetDelegateForFunctionPointer будет работать, но вам нужно добавить [MarshalAs(UnmanagedType.LPWStr)] Атрибут для параметра в вашей декларации делегата для того, чтобы String превращаться в wchar_t*:

delegate void MyDelegate([MarshalAs(UnmanagedType.LPWStr)] string foo)

IntPtr func = ...;
MyDelegate del = (MyDelegate)Marshal.GetDelegateForFunctionPointer(func,
                                 typeof(MyDelegate));

Чтобы передать изменяемую строку, дайте StringBuilder, Вам необходимо явно зарезервировать пространство для работы неуправляемой функции:

delegate void MyDelegate([MarshalAs(UnmanagedType.LPWStr)] StringBuilder foo)

StringBuilder sb = new StringBuilder(64); // reserve 64 characters.

del(sb);

Увидеть малоизвестный UnmanagedFunctionPointer атрибут, который похож DllImport для делегатов, если вы хотите использовать CharSet или еще много чего.

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