Speichern von UTF-8-string in einen UnicodeString
In Delphi 2007 können Sie speichern eine UTF-8-string in einen WideString ausführt und dann den pass, der auf einer Win32-Funktion, z.B.
var
UnicodeStr: WideString;
UTF8Str: WideString;
begin
UnicodeStr:='some unicode text';
UTF8Str:=UTF8Encode(UnicodeStr);
Windows.SomeFunction(PWideChar(UTF8Str), ...)
end;
Delphi 2007 hat keinen Einfluss auf die Inhalte der UTF8Str, d.h. es ist Links wie ein UTF-8 kodierter string gespeichert, in einen WideString ausführt.
Aber in Delphi 2010 bin ich kämpfen, um einen Weg finden, um das gleiche zu tun, also speichern einer UTF-8 kodierten string in einen WideString ausführt, ohne dass es automatisch konvertiert von UTF-8. Ich kann mich nicht übergeben Sie einen Zeiger auf eine UTF-8-string (oder RawByteString), z.B. die folgenden, wird offensichtlich nicht funktionieren:
var
UnicodeStr: WideString;
UTF8Str: UTF8String;
begin
UnicodeStr:='some unicode text';
UTF8Str:=UTF8Encode(UnicodeStr);
Windows.SomeFunction(PWideChar(UTF8Str), ...)
end;
- Ich aktualisiert meine Antwort mit der Lösung.
- Zur info, die original-2007-code stört mit der UTF-8-Daten. Im Jahr 2007
UTF8Encode()
zurückgegeben UTF-8-codierteAnsiString
. In jeder version, die Zuweisung einerAnsiString
zu einemWideString
führt eine Ansi->UTF16-Wandlung mit der OS-Standard-Ansi-codepage. Die endgültigeWideString
NICHT enthalten UTF-8-Daten. Es enthält die UTF-16-Daten. Die Umwandlung hat kein Konzept, dass UTF-8 vorhanden war, und somit wahrscheinlich zu einer Beschädigung der Daten, wenn der ursprüngliche Eingang verwendet wird beliebige nicht-ASCII-Zeichen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihrer ursprünglichen Delphi 2007 war der code für die Konvertierung der UTF-8-string in einen widestring mit dem ANSI-Zeichensatz. Tun die gleiche Sache in Delphi 2010, die Sie verwenden sollten SetCodePage mit dem parameter Convert false.
Hmm, warum machst du das? Warum sind Sie die Codierung von einem WideString in UTF-8 einfach zu speichern, wieder zurück auf WideString. Sie sind offensichtlich mit einem Unicode-version der Windows-API. So gibt es keine Notwendigkeit zur Verwendung eines UTF-8-codierte Zeichenfolge. Oder bin ich etwas fehlt.
Da die Windows-API-Funktionen sind entweder Unicode-Zeichen (zwei bytes) oder ANSI (ein byte). UTF-8 wäre falsch hier die Wahl, vor allem, weil es enthält ein byte pro Zeichen, sondern für die Zeichen oberhalb des ASCII-Basis es verwendet zwei oder mehr bytes.
Sonst das äquivalent für Ihren alten code in unicode-Delphi wäre:
WideString und string (UnicodeString) sind ähnlich, aber die neue UnicodeString ist schneller, denn es ist Referenz-gezählt und für WideString nicht.
Ihr code war nicht korrekt, weil die UTF-8-Zeichenkette hat eine variable Anzahl von bytes pro Zeichen. "Ein" wird gespeichert als ein byte. Nur ein ASCII-byte-code. "ü" auf der anderen Seite würde gespeichert werden in zwei bytes. Und da sind Sie dann mit PWideChar übernimmt die Funktion erwartet immer zwei bytes pro Zeichen.
Es ist auch ein Unterschied. In älteren Delphi-Versionen (ANSI) Utf8String war nur ein AnsiString. In den Unicode-Versionen von Delphi Utf8String ist ein string mit einem UTF-8-Codepage dahinter. So verhält es sich anders.
Sich der alte code immer noch korrekt:
Wäre es das gleiche handeln wie in Delphi 2007. So haben Sie vielleicht ein problem an anderer Stelle.
Mick sind Sie richtig. Der compiler hat einige zusätzliche Arbeit hinter den kulissen. Also um dies zu vermeiden, können Sie etwas wie das hier tun:
Habe ich geprüft, und es funktioniert genauso. Da bewege ich mich bytes direkt im Speicher gibt es keine codepage-Konvertierung erfolgt im hintergrund. Ich bin sicher, dass es getan werden kann, mit größerer eleganece, aber der Punkt ist, ich sehe dies als den Weg für das, was Sie erreichen wollen.
AnsiString
den letztenWideString
. Das gleiche galt auch in der original-D2007-code. Aber auf einer seitlichen Anmerkung, können Sie vermeiden, die tempAnsiString
mithilfeSetCodePage()
auf dieRawByteString
, dann können Sie ordnen Sie dieRawByteString
zu denWideString
.Die Windows-API-Aufruf will mit dir einen UTF-8 string? Entweder es wird ein ANSI-string oder Widestring (A-oder W-Funktionen). Widestrings haben zwei bytes pro Zeichen, und UTF-8-strings mit einem (oder mehr, wenn Sie jenseits der ersten 128 ASCII-Zeichen).
UTF-8 in einen Widestring einfach nicht sinnvoll. Wenn es wirklich eine Windows-Funktion will einen pointer auf ein UTF-8-Zeichenfolge, die Sie haben wahrscheinlich zu wirken, ist ein PAnsiChar.