Question

Je recevais conseil de Rob Kennedy et l’une de ses suggestions pour augmenter considérablement la vitesse d’une application sur laquelle je travaillais consistait à utiliser SetString , puis à le charger dans le composant VCL qui était affiché. il.

J'utilise Delphi 2009, maintenant que PChar est Unicode,

SetString(OutputString, PChar(Output), OutputLength.Value);
edtString.Text := edtString.Text + OutputString;

Fonctionne et je l'ai changé moi-même en PChar, mais puisque les données déplacées ne sont pas toujours Unicode, il s'agit généralement de données ShortString .... donc sur ce qu'il m'a réellement donné à utiliser:

SetString(OutputString, PAnsiChar(Output), OutputLength.Value);
edtString.Text := edtString.Text + OutputString;

Rien ne s'affiche, mais je vérifie dans le débogueur et le texte qui apparaît normalement de la façon dont je le faisais, construisant 1 caractère à la fois, était dans la variable.

Curieusement, ce n’est pas la première fois que je rencontre ce soir. Parce que j'essayais de trouver une autre solution, j'ai suivi une partie de ses conseils. Au lieu de construire dans un TCaption de VCL, je l'ai intégrée dans une variable chaîne puis je l'ai copiée, mais rien ne s'affiche lorsque je l'envoie. Une fois encore dans le débogueur, la variable dans laquelle les données sont générées ... contient les données.

for I := 0 to OutputLength.Value - 1 do
begin
  OutputString := OutputString + Char(OutputData^[I]);
end;
edtString.Text := OutputString;

Ce qui précède ne fonctionne pas, mais l'ancienne méthode lente de le faire fonctionnait très bien ....

for I := 0 to OutputLength.Value - 1 do
begin
  edtString.Text := edtString.Text + Char(OutputData^[I]);
end;

J'ai essayé de transformer la variable en ShortString, String et TCaption et rien ne s'affiche. Ce que je trouve également intéressant, c’est que pendant que je construis mes données hexadécimales à partir du même tableau en un richedit, c’est très rapide, alors que le faire dans une édition est très lent. C’est la raison pour laquelle je n’ai pas pris la peine de changer le code du richedit car il fonctionne très rapidement.

Modifier pour ajouter - Je pense que j’ai trouvé le problème mais je n’ai pas de solution. Si je modifie la valeur dans le débogueur pour supprimer tout ce qui ne peut pas être affiché (ce qui, par l'ancienne méthode, ne l'affichait tout simplement pas ... échouait), alors ce qu'il me restait serait affiché. Donc, s’il s’agit juste de supprimer les octets qui ont été transformés en caractères incohérents, comment puis-je résoudre ce problème?

J'ai en gros des données brutes entrantes provenant d'un périphérique SCSI qui sont affichées dans le style éditeur hexadécimal. Mon style lent d'origine consistant à ajouter un caractère à la fois affichait avec succès des chaînes et des chaînes Unicode ne contenant pas de caractères Unicode spécifiques. Les méthodes les plus rapides, même si elles fonctionnent, n’afficheront pas ShortStrings d’une manière et l’autre ne affichera pas de chaînes Unicode qui n’utilisent pas de caractères autres que 0 à 255. J'aime beaucoup et je pourrais utiliser le gain de vitesse, mais si cela signifie sacrifier la capacité de lire la chaîne ... alors quel est le but de l'application?

EDIT3 - Très bien maintenant que j’ai compris que 0-31 est un caractère de contrôle et que 32 ans et plus est valide, je pense que je vais essayer de filtrer les caractères et remplacer ceux qui ne sont pas valides par un. qui est quelque chose que je prévoyais de faire plus tard pour émuler le style éditeur hexadécimal.

S'il y a d'autres suggestions, je serais ravie d'en entendre parler, mais je pense que je peux concevoir une solution plus rapide que l'original et en faire ce dont j'ai besoin en même temps.

Était-ce utile?

La solution

J'ai utilisé PAnsiChar dans mon exemple pour une raison. Il semblait que OutputLength était mesuré en octets, et non en caractères. Je me suis donc assuré d'utiliser un type dont la longueur est toujours mesurée en octets. Vous remarquerez également que j'ai affiché la déclaration de OutputString sous la forme d'un AnsiString .

Depuis le contrôle d'édition stocké dans Unicode, cependant, il y aura une conversion entre AnsiString et UnicodeString . Cela prendra en compte la page de code actuelle du système, mais ce n'est probablement pas ce que vous voulez. Vous voudrez peut-être déclarer la variable en tant que RawByteString . Aucune page de code n'y sera associée, il n'y aura donc pas de conversions inattendues.

N'utilisez pas de chaînes pour stocker des données binaires. Si vous construisez ce qui équivaut à un éditeur hexadécimal, vous travaillez avec des données binaires. C'est important de s'en souvenir. Même si vos données binaires sont composées principalement d'octets pouvant être interprétés comme du texte, vous ne pouvez pas traiter ces données sous forme de texte, sinon vous rencontrerez exactement les problèmes que vous rencontrez & # 8212 ; caractères qui n'apparaissent pas comme prévu. Si vous recevez plusieurs octets de votre périphérique SCSI, stockez-les dans un tableau d'octets et non de caractères.

Dans les éditeurs hexadécimaux, vous remarquerez qu’ils affichent toujours les valeurs hexadécimales des octets. Ils peuvent montrer ces octets interprétés comme des caractères, mais c'est secondaire et ils ne montrent généralement que les octets pouvant représenter des caractères ASCII; ils n'essayent pas d'être trop sophistiqués avec l'affichage de base. Les éditeurs hexadécimaux bons proposent également d’afficher les données interprétées comme des caractères larges. Cela facilite le débogage car l'utilisateur peut consulter les mêmes données de plusieurs manières. Mais ce ne sont que des vues des données. Ils ne modifient pas réellement le contenu binaire des données.

Autres conseils

Quelques commentaires:

  1. Votre question n'est pas très claire. Que voulez-vous faire exactement?
  2. Votre question est terrible, vérifiez votre texte avec un vérificateur d'orthographe.
  3. La question à laquelle vous faites référence est la suivante: Delphi accédant aux données d'un tableau dynamique rempli d'un pointeur non typé
  4. Veuillez donner un exemple de code complet de votre fonction, comme vous l'avez fait dans votre question précédente. Je veux savoir si vous avez appliqué la suggestion de Rob Kennedy ou le code que vous avez vous-même donné dans une réponse suivante (espérons que ce n'est pas :))
  5. Pour l’instant, je comprends votre question: vous envoyez une requête à votre périphérique SCSI et vous récupérez un tableau d’octets que vous stockez dans la variable OutputData. Après cela, vous voulez montrer vos données à l'utilisateur. Votre vraie question est donc la suivante: Comment afficher un tableau d'octets à l'utilisateur?
  6. Connectez-vous en tant que même utilisateur et ne créez pas de compte pour chaque nouvelle question. Ainsi, nous pouvons suivre l'historique de vos questions et savoir ce que vous entendez par "obtenir des conseils".

Certaines hypothèses et suggestions, si j'ai raison, sur le vrai sens de votre question:

  1. Afficher vos données sous forme de chaîne hexagonale ne posera aucun problème
  2. Afficher vos données dans un champ Mémo normal vous pose des problèmes, même si une chaîne Delphi peut contenir n’importe quel caractère, y compris 0 octet, leur affichage vous posera des problèmes. Un TMemo, par exemple, affichera vos données jusqu'au premier octet. Ce que vous devez faire (et vous avez donné la réponse vous-même), c'est remplacer les caractères non visibles par un mannequin. Après cela, vous pouvez afficher vos données dans un TMemo. En réalité, tous les visualiseurs hexagonaux font la même chose, les caractères qui ne peuvent pas être imprimés seront affichés par un point.

Lorsque vous filtrez les caractères non visibles, vous devrez probablement décider quoi faire avec quelques-uns, tels que # 9 (Tab), # 10 (LF), # 11 (Verticle Tab), # 12. (FF ou Nouvelle page), n ° 13 (CR)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top