2008-12-20 8 views
9

Contexte: Cette question concerne les versions de Delphi inférieures à 2009 (c'est-à-dire sans le support Unicode intégré). J'ai une spécification qui me demande de transmettre une chaîne codée Unicode via une connexion TCP, mais je n'ai pas Delphi 2009.Gestion d'une chaîne Unicode dans les versions Delphi <= 2007

Question Y at-il une seule fonction ou très petite bibliothèque (je ne suis pas besoin de trop en vrac) que je peux utiliser pour encoder une seule chaîne en UTF-8 immédiatement avant d'envoyer le fil? Comme deuxième partie de ma question: si des chaînes codées en UTF-8 sont renvoyées en réponse, je suppose que j'aurais besoin d'une autre fonction pour le remettre dans un format de chaîne Delphi. Je comprends les limites de ce support Unicode de cette manière.

+0

Qu'en est-il de Utf8ToAnsi et AnsiToUtf8 situés dans system.pas? –

Répondre

26

versions Delphi avant Delphi 2009 faire ont le support Unicode intégré. Le type WideString est disponible depuis Delphi 4, je pense, peut-être plus tôt. WideString n'est pas aussi joli que le nouveau type UnicodeString, mais il contient toujours des caractères Unicode 16 bits, et vous pouvez le dactylographier en PWideChar pour envoyer des chaînes aux fonctions de l'API Unicode. L'unité Windows déclare la plupart des versions "larges" des fonctions de l'API, et rien ne vous empêche de déclarer d'autres fonctions si vous en trouvez certaines manquantes.

Ce que les versions antérieures n'ont pas, c'est le support Unicode dans la VCL. Pour cela, vous pouvez utiliser les contrôles Tnt Unicode. Ils étaient libres. On dirait qu'il existe quelques endroits où la dernière version gratuite est encore disponible: (1), (2). Le JCL a quelques unités pour travailler avec Unicode. L'unité JclWideStrings a principalement des fonctions utilitaires légères. L'unité JclUnicode est plus complète, mais elle inclut également une ressource importante pour déterminer les propriétés de caractères de tous les caractères Unicode.

Avec le langage JCL, vous avez plusieurs choix pour que les classes contiennent des valeurs de WideString. Je pense que Delphi 7 vient même avec un cours pour ça.

Ne pensez pas que vous ne pouvez pas écrire un programme Unicode simplement parce que vous n'avez pas Delphi 2009.

Si vous avez une valeur WideString, et que vous souhaitez encoder en UTF-8, puis appeler la fonction Utf8Encode. Il renverra une valeur AnsiString, ou éventuellement Utf8String, si votre version Delphi déclare ce type. Ce n'est pas la même chose que le type Utf8String de Delphi 2009, cependant.Delphi 2009 sera automatiquement convertir en UnicodeString ou AnsiString(x) et vice versa dans les instructions d'affectation. Les versions antérieures ne disposent que d'un seul type AnsiString, vous devez donc suivre vous-même les variables qui contiennent des données UTF-8 et qui contiennent des données Ansi. (La notation hongroise sur vos noms de variable et de paramètre peut vous aider à garder la trace.) Et bien sûr, il y a aussi une fonction Utf8Decode pour convertir les données UTF-8 en WideString.

Pour gérer d'autres codages de caractères, vous souhaitez consulter Open XML, une bibliothèque XML gratuite pour Delphi. Dans le cadre de sa gestion XML, il prend en charge la conversion de 70 encodages différents.

+2

Prior Delphi 2009, si vous affectez une chaîne WideString à une chaîne, vous aurez une conversion automatique d'Unicode en chaîne = AnsiString, avec la page de codes actuelle du processus. Utf8Decode/Utf8Encode sont nécessaires si vous souhaitez utiliser UTF-8 à la place de la page de codes actuelle pour le stockage sintr. –

+0

Ce lien vers le JCL semble être obsolète. Est-ce que http://wiki.delphi-jedi.org/index.php?title=JEDI_Code_Library est l'équivalent actuel? –

6

Utilisez le type WideString et fonctions d'encodage à/de UTF8 (UTF8Encode/UTF8Decode)

Ne pas utiliser le type de chaîne et ne pas utiliser Ansi-fonctions - si vous faites cela, vous perdez des informations.

+0

Si OP est conscient des limitations de ce support Unicode, et que toutes les chaînes encodées en UTF-8 en question sont convertibles vers et à partir du charset système actuel sans aucune perte d'informations, alors cette réponse est fausse. – mghie

5

La conversion d'une application pré-Delphi 2009 en unicode est difficile mais faisable. Je le diviserais en 3 tâches. Tout d'abord, assurez-vous que votre base de données gère les chaînes Unicode. De préférence, support UTF-16. Assurez-vous que tout le code de votre base de données gère correctement les chaînes, et les pilotes que vous utilisez gèrent également cela.

  • Convertissez toute votre logique métier en utilisant des chaînes pour utiliser WideStrings. Il est très facile d'en manquer, et vous n'obtiendrez aucune erreur, car le compilateur convertira implicitement la chaîne large en chaîne si vous oubliez des méthodes. Veillez également à modifier toutes les fonctions de chaîne standard en équivalents WideString. Ce processus doit s'étendre à tous les composants tiers que vous pouvez utiliser.
  • La dernière partie consiste à modifier les composants visuels standards et tiers que vous pouvez avoir en équivalents WideString. Cela doit être fait partout où vous allez afficher des chaînes qui peuvent contenir des caractères Unicode. En plus de tout cela, assurez-vous que vos tests sont complets, et utilise des caractères Unicode qui utilisent réellement l'octet de poids fort. Si vous testez simplement en utilisant le jeu de caractères latin, vous manquerez des bugs.

  • +0

    Pourquoi le support UTF-16 est-il nécessaire dans la base de données? UTF-8 serait un bien meilleur ajustement pour un programme Ansi Delphi, qui utiliserait très probablement des fonctions de conversion système pour Ansi <-> UTF-8. – mghie

    +0

    Utiliser WideString (non référencé, COM lourd) pour UTF-16 Utilisez TUtf8String/string (référence comptée, légère) pour UTF-8, assurez-vous de faire quelque chose comme "type TUtf8String = type string;" pour rendre le TUtf8String distinct mais compatible avec la chaîne. –

    3

    Si tout ce que vous avez à faire est en effet de convertir vos chaînes internes au programme de l'encodage système en UTF-8 et vice versa, alors utilisez les fonctions de bibliothèque mentionnées par Uwe Raabe. Si vous êtes encore sur Delphi 4 ou 5 (qui n'ont pas ces fonctions), vous pouvez utiliser les fonctions qui sont dans GNU gettext for Delphi. Et ne laissez pas toutes les réponses à propos d'aller complètement WideString vous effrayer - en utilisant UTF-8 comme encodage pour l'échange de données (c'est comme ça que je comprends votre question) devrait être possible dans un programme Ansi Delphi normal sans gros problèmes , tant que vous traitez des données 100% représentables dans votre encodage Windows.

    6

    J'ai construit une application Unicode complète sans utiliser Delphi 2009 (avant sa sortie).

    Je l'ai utilisé comme suit:

    1. Utilisez WideString comme principal type de données de chaîne.

    2. Composant de base de données utilisé avec un support Unicode (ADO utilise aussi le formatage, mais je ne l'ai pas utilisé car il ne gère pas les noms de champs Unicode).

    3. Utilisé gratuitement TNTControls pour l'interface utilisateur, a bien fonctionné, mais c'est pareil que les contrôles standard, n'ont pas beaucoup de fonctionnalités comme les contrôles d'autres tiers. J'ai configuré une VM avec une langue différente, donc je peux tester la version dans un système différent qui ne supporte pas ma langue. FastReport était mon outil de reporting qui supporte aussi Unicode.

    aussi je l'ai utilisé DIConverters de Inspiration Delphi pour convertir une base de données ansi à UTI8 avec ses fonctions, vous pouvez l'utiliser pour la conversion de/vers UTF8, et il est freeware ;-)

    il y a aussi un projet open source Delphi fundamentals, qui ont une fonction utile pour unicode.

    mais je pense que si vous pouviez utiliser D2009 pour le support complet de l'Unicode, votre travail sera beaucoup plus facile et plus rapide, car vous n'utiliserez pas un type de données lent, et vous trouverez une version Unicode ou travaille maintenant dessus.

    Questions connexes