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

Я пишу библиотеку 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 ]

7 голосов
/ 08 июня 2011

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);
2 голосов
/ 22 июля 2011

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

...