Umwandlung in .net: Native Utf-8 <-> String Verwaltet
Erstellt habe ich diese beiden Methoden zum konvertieren von Nativen utf-8-strings (char*) in verwalteten string und Umgekehrt. Der folgende code macht den job:
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);
}
Während NativeUtf8FromString ist ok, StringFromNativeUtf8 ist ein Chaos, aber das einzige, safe code, den ich bekommen konnte, um zu laufen. Mit unsafe code, den ich verwenden könnte, ein byte* aber ich will nicht unsicherer code. Gibt es einen anderen Weg kann sich jemand denken, wo ich nicht kopieren Sie die Zeichenfolge für jede enthaltene byte zu finden, die 0-Terminierung.
Ich einfach das " unsicheres code hier:
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);
}
Als Sie sehen nicht hässlich muss einfach nur unsicher.
- Warum haben Sie Sorge, nicht mit
unsafe
code? - Sicher nicht. Da Procect aktivieren muss /unsicher Schalter, der fühlt sich schmutzig zu mir.
- Die
/unsafe
Schalter ist ziemlich sinnlos.Marshal.*
ist genauso unsicher wie Zeiger-code, auch wenn es nicht erforderlich ist, den Schalter. - Ich bin völlig einverstanden, dass eine Rangierung ist so unsicher wie die Zeiger-code, aber ich dachte, dass sein Wert eine Frage. Vielleicht gibt es eine einfache Lösung, die ich einfach nicht finden.
- Sicher /unsicher bedeutet, Sie können brechen die CLR, und dem Marschall nicht zulassen, werden Sie das tun?
Marshal.Copy
können Sie zum schreiben von Daten in beliebigen Speicherbereichen, wie Zeiger ermöglichen Ihnen das schreiben von Daten auf beliebige Speicherorte. Kein Unterschied im Schaden, den Sie tun können.- es ist ein großer Unterschied, weshalb man unsicher ist und der andere nicht. Dies ist nicht der Ort zu diskutieren -- Fragen, eine Frage, wenn Sie möchten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur führen Sie den gleichen Vorgang strlen() führt. Tun, überlegen Sie, ob Sie die Puffer herum, der code wird generiert Müll in Eile.
Etwas schneller als Hans' Lösung (1 weniger Puffer kopieren):
Hier ist ich demo round-tripping string: