Creé esos dos métodos para convertir cadenas utf-8 nativas (char *) en cadenas administradas y viceversa. El siguiente código hace el trabajo:Conversión en .net: Nativo Utf-8 <-> Cadena administrada
public IntPtr NativeUtf8FromString(string managedString)
{
byte[] buffer = Encoding.UTF8.GetBytes(managedString); // not null terminated
Array.Resize(ref buffer, buffer.Length + 1);
buffer[buffer.Length - 1] = 0; // terminating 0
IntPtr nativeUtf8 = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, nativeUtf8, buffer.Length);
return nativeUtf8;
}
string StringFromNativeUtf8(IntPtr nativeUtf8)
{
int size = 0;
byte[] buffer = {};
do
{
++size;
Array.Resize(ref buffer, size);
Marshal.Copy(nativeUtf8, buffer, 0, size);
} while (buffer[size - 1] != 0); // till 0 termination found
if (1 == size)
{
return ""; // empty string
}
Array.Resize(ref buffer, size - 1); // remove terminating 0
return Encoding.UTF8.GetString(buffer);
}
Mientras NativeUtf8FromString está bien, StringFromNativeUtf8 es un desastre, pero el único código de seguridad que pudiera llegar a funcionar. Usando un código inseguro podría usar un byte * pero no quiero un código inseguro. ¿Hay alguna otra forma en que alguien pueda pensar que no tengo que copiar la cadena por cada byte contenido para encontrar la terminación 0?
simplemente agrego el código unsave aquí:
public unsafe string StringFromNativeUtf8(IntPtr nativeUtf8)
{
byte* bytes = (byte*)nativeUtf8.ToPointer();
int size = 0;
while (bytes[size] != 0)
{
++size;
}
byte[] buffer = new byte[size];
Marshal.Copy((IntPtr)nativeUtf8, buffer, 0, size);
return Encoding.UTF8.GetString(buffer);
}
Como se puede ver que no es fea sólo tiene inseguro.
¿Por qué te preocupa no utilizar el código 'inseguro'? – CodesInChaos
@CodelnChaos: No estoy seguro. Porque Procect tiene que activar el interruptor/inseguro que me parece sucio. – Totonga
El interruptor '/ inseguro' no tiene sentido. 'Marshal. *' Es tan inseguro como el código del puntero, incluso si no requiere el cambio. – CodesInChaos