Ten en cuenta que en las ciencias informáticas un problema casi siempere puede tener diversas soluciones, de igual modo nosotros aquí compartiremos la mejor y más óptimo.
Solución:
[MarshalAs(UnmanagedType.LPStr)] – ¿Cómo convierte esto cadenas utf-8 a char*?
no lo hace No existe tal cosa como un “utf-8 string” en el código administrado, las cadenas siempre se codifican en utf-16. La clasificación desde y hacia un LPStr se realiza con la página de códigos predeterminada del sistema. Lo que hace que sea bastante notable que vea glifos coreanos en el depurador, a menos que use la página de códigos 949 .
Si la interoperabilidad con utf-8 es un requisito difícil, entonces necesita usar un byte[] en la declaración pinvoke. Y convierta usted mismo de un lado a otro con System.Text.Encoding.UTF8. Use su método GetString() para convertir el byte[] a un stringsu método GetBytes() para convertir un string a byte[]. Evite todo esto si es posible usando wchar_t[] en el código nativo.
Si bien las otras respuestas son correctas, ha habido un desarrollo importante en .NET 4.7. Ahora hay una opción que hace exactamente lo que necesita UTF-8: UnmanagedType.LPUTF8Str
. Lo probé y funciona como un cronómetro suizo, haciendo exactamente lo que parece.
De hecho, incluso usé MarshalAs(UnmanagedType.LPUTF8Str)
en un parámetro y MarshalAs(UnmanagedType.LPStr)
en otro. También funciona. Aquí está mi método (toma en string parámetros y devuelve un string a través de un parámetro):
[DllImport("mylib.dll", ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern void ProcessContent([MarshalAs(UnmanagedType.LPUTF8Str)]string content,
[MarshalAs(UnmanagedType.LPUTF8Str), Out]StringBuilder outputBuffer,[MarshalAs(UnmanagedType.LPStr)]string settings);
¡Gracias, Microsoft! Otra molestia se ha ido.
Si necesita ordenar UTF-8 string
hazlo manualmente.
Definir función con IntPtr
en lugar de string:
somefunction(IntPtr text)
Luego convierta el texto a UTF8 terminado en cero array de bytes y escribirlos en IntPtr
:
byte[] retArray = Encoding.UTF8.GetBytes(text);
byte[] retArrayZ = new byte[retArray.Length + 1];
Array.Copy(retArray, retArrayZ, retArray.Length);
IntPtr retPtr = AllocHGlobal(retArrayZ.Length);
Marshal.Copy(retArrayZ, 0, retPtr, retArrayZ.Length);
somefunction(retPtr);
Más adelante puedes encontrar las referencias de otros programadores, tú de igual forma tienes la libertad de dejar el tuyo si lo deseas.