una - eventos delegados c#
Pasar un puntero a la funciĆ³n de C++ para ser llamado por C#- Los argumentos de las funciones incluyen una cadena de caracteres ancha(LPCWSTR) (2)
Estoy escribiendo una biblioteca de C # para ser utilizada por la aplicación C ++ nativa. Estoy usando C ++ / CLI como el mecanismo de interoperabilidad.
Necesito pasar una función de devolución de llamada de C ++ a C # (usando C ++ / CLI como la capa intermedia). La biblioteca C # necesita llamar a la función C ++ con una cadena terminada en cero de caracteres anchos; es decir, el prototipo de la función de devolución de llamada es
Func (LPCWSTR pszString);
Hay otros parámetros pero son irrelevantes para esta discusión.
Busqué en la red y encontré el método Marshal.GetDelegateForFunctionPointer que puedo usar. El problema con esto es que convierte System.String de C # a char * y no a wchar_t * que estoy buscando.
Además, ¿cuál es el mejor método para lograr este ejemplo de código incluyendo la parte de C ++ / CLI, si es posible? C ++ / CLI dll depende de C # dll. El método debe llamarse sincrónicamente.
Consulte el atributo UnmanagedFunctionPointer
poco conocido, que es como DllImport
para delegados, si desea usar CharSet
o lo que sea.
GetDelegateForFunctionPointer
funcionará, pero debe agregar un [MarshalAs(UnmanagedType.LPWStr)]
al parámetro en su declaración de delegado para que String
se convierta en wchar_t*
:
delegate void MyDelegate([MarshalAs(UnmanagedType.LPWStr)] string foo)
IntPtr func = ...;
MyDelegate del = (MyDelegate)Marshal.GetDelegateForFunctionPointer(func,
typeof(MyDelegate));
Para pasar una cadena modificable , dale un StringBuilder
. Debe reservar espacio de forma explícita para que la función no administrada funcione:
delegate void MyDelegate([MarshalAs(UnmanagedType.LPWStr)] StringBuilder foo)
StringBuilder sb = new StringBuilder(64); // reserve 64 characters.
del(sb);