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.

InformationsquelleAutor Totonga | 2012-05-27
Schreibe einen Kommentar