Le stockage de chaîne UTF-8 dans un UnicodeString
En Delphi 2007, vous pouvez stocker une chaîne UTF-8 dans un WideString et puis passer que sur une fonction Win32, par exemple
var
UnicodeStr: WideString;
UTF8Str: WideString;
begin
UnicodeStr:='some unicode text';
UTF8Str:=UTF8Encode(UnicodeStr);
Windows.SomeFunction(PWideChar(UTF8Str), ...)
end;
Delphi 2007 n'interfère pas avec le contenu de UTF8Str, c'est-à gauche comme une codé en UTF-8 chaîne stockée dans un WideString.
Mais en Delphi 2010 j'ai du mal à trouver un moyen de faire la même chose, c'est à dire stocker une codé en UTF-8 chaîne de caractères dans une WideString sans qu'il soit automatiquement converti en UTF-8. Je ne peux pas passer un pointeur vers une chaîne UTF-8 (ou RawByteString), par exemple, la suivante ne fonctionne évidemment pas:
var
UnicodeStr: WideString;
UTF8Str: UTF8String;
begin
UnicodeStr:='some unicode text';
UTF8Str:=UTF8Encode(UnicodeStr);
Windows.SomeFunction(PWideChar(UTF8Str), ...)
end;
J'ai mis à jour ma réponse avec la solution.
Pour info, l'original 2007 code NE interférer avec les données UTF-8. En 2007,
Pour info, l'original 2007 code NE interférer avec les données UTF-8. En 2007,
UTF8Encode()
retourné une codé en UTF-8 AnsiString
. Dans chaque version, l'attribution d'une AnsiString
à un WideString
effectue Ansi->UTF16 la conversion en utilisant le système d'exploitation par défaut de la page de codes Ansi. La finale WideString
NE contient PAS de données UTF-8. Il contient les données UTF-16. La conversion n'a pas de concept que de l'UTF-8 était présent, et ne sont donc susceptibles de corrompre les données en cas d'entrée d'origine utilise des caractères non-ASCII.OriginalL'auteur Mick | 2010-04-23
Vous devez vous connecter pour publier un commentaire.
Votre origine Delphi 2007 code a été la conversion de la chaîne UTF-8 pour une widestring à l'aide de la page de codes ANSI. Pour faire la même chose en Delphi 2010, vous devez utiliser SetCodePage avec le de Convertir le paramètre false.
Merci, cela fonctionne parfaitement!
OriginalL'auteur Zoë Peterson
Hmm, pourquoi tu fais ça? Pourquoi êtes-vous de l'encodage d'une WideString de l'UTF-8 juste pour stocker de nouveau de retour à WideString. Vous êtes de toute évidence à l'aide d'une version Unicode de l'API Windows. Donc, il n'est pas nécessaire d'utiliser de l'UTF-8-chaîne codée. Ou ai-je raté quelque chose.
Parce que les fonctions de l'API Windows sont des caractères Unicode (deux octets) ou ANSI (un octet). UTF-8 serait un mauvais choix ici, car il contient un octet par caractère, mais pour les personnages au-dessus de l'ASCII de base, il utilise deux octets ou plus.
Sinon l'équivalent de votre ancien code unicode Delphi serait:
WideString et de chaîne (UnicodeString) sont similaires, mais la nouvelle UnicodeString est plus rapide car il est la référence comptés et WideString ne l'est pas.
Vous code n'est pas correct parce que la chaîne UTF-8 dispose d'un nombre variable d'octets par caractère. "Un" est stocké sur un octet. Juste un ASCII en byte code. "ü" sur l'autre main est stockée en tant que deux octets. Et parce que vous êtes alors à l'aide de PWideChar la fonction attend toujours deux octets par caractère.
Il y a une autre différence. Dans les anciennes versions de Delphi (ANSI) Utf8String était juste un AnsiString. Dans Unicode versions de Delphi Utf8String est une chaîne UTF-8 code de la page derrière elle. De sorte qu'il se comporte différemment.
L'ancien code fonctionne encore correctement:
Il serait agir comme il l'a fait en Delphi 2007. Alors peut-être vous avez un problème ailleurs.
Mick vous sont corrects. Le compilateur fait un peu de travail supplémentaire derrière la scène. Afin d'éviter cela, vous pouvez faire quelque chose comme ceci:
J'ai vérifié, et il fonctionne de la même façon. Parce que je déménage octets directement dans la mémoire il n'y a pas de conversion de page de codes effectuée en arrière-plan. Je suis sûr qu'il peut être fait avec la plus grande eleganece, mais le point est que je vois cela comme la voie à ce que vous voulez atteindre.
AnsiString
à la finaleWideString
. La même chose est vraie dans l'original D2007 code. Mais sur une note de côté, vous pouvez éviter le tempAnsiString
en utilisantSetCodePage()
sur leRawByteString
, puis vous pouvez affecter laRawByteString
à laWideString
.OriginalL'auteur Runner
Qui l'API Windows vous souhaite de passer une chaîne UTF-8? C'est soit une chaîne ANSI ou un Widestring (A ou W fonctions). Widestrings ont deux octets par caractère, et des chaînes UTF-8 (ou plus si vous-delà de la première 128 caractères ASCII).
UTF-8 dans une Widestring n'a tout simplement pas de bon sens. Quand il y a vraiment une fonction de Windows qui veut un pointeur vers une chaîne UTF-8, vous avez probablement de fonte est un PAnsiChar.
OriginalL'auteur The_Fox