Pregunta

Estaba obteniendo consejo de Rob Kennedy y una de sus sugerencias que aumentó enormemente la velocidad de una aplicación en la que estaba trabajando era usar SetString y luego cargarlo en el componente VCL que se mostraba

Estoy usando Delphi 2009, ahora que PChar es Unicode,

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

Funciona y lo cambié a PChar yo mismo, pero dado que los datos que se mueven no siempre son Unicode, de hecho, generalmente son datos de cadena corta ... así que lo que realmente me dio para usar:

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

No aparece nada pero verifiqué el depurador y el texto que normalmente aparecía como lo hice construyendo 1 carácter a la vez en el pasado estaba en la variable.

Curiosamente, esta no es la primera vez que me encuentro con esto esta noche. Debido a que estaba tratando de llegar a otra forma, tomé parte de su consejo y, en lugar de incorporarlo a una TCaption de VCL, lo construí en una variable de cadena y luego lo copié, pero cuando lo envío no se muestra nada. Una vez más en el depurador, la variable en la que están integrados los datos ... tiene los datos.

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

Lo anterior no funciona, pero la vieja forma lenta de hacerlo funcionó bien ...

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

Intenté convertir la variable en ShortString, String y TCaption y no se muestra nada. Lo que también me parece interesante es que mientras construyo mis datos hexadecimales de la misma matriz en una riqueza, es muy rápido, mientras que hacerlo dentro de una edición para los datos de texto es muy, muy lento. Es por eso que no me he molestado en tratar de cambiar el código para el richedit, ya que funciona súper rápido como es.

Editar para agregar: creo que encontré el problema, pero no tengo solución. Si edito el valor en el depurador para eliminar todo lo que no se puede mostrar (que por el método anterior solía no mostrarse ... no falla), se muestra lo que me queda. Entonces, si solo se trata de deshacerse de los bytes que se convirtieron en caracteres que son basura, ¿cómo puedo solucionarlo?

Básicamente, tengo datos sin procesar entrantes de un dispositivo SCSI que se muestra al estilo de editor hexadecimal. Mi estilo lento original de agregar un carácter a la vez mostraba con éxito cadenas y cadenas Unicode que no tenían caracteres específicos de Unicode en ellas. Los métodos más rápidos, incluso si funcionan, no mostrarán ShortStrings de una manera y la otra no mostrarán UnicodeStrings que no usan caracteres que no sean 0-255. Realmente me gusta y podría usar el aumento de velocidad, pero si eso significa sacrificar la capacidad de leer la cadena ... entonces, ¿cuál es el punto en la aplicación?

EDIT3 - Bien, ahora que he descubierto que 0-31 es control char y 32 y más es válido, creo que voy a intentar filtrar char y reemplazar aquellos que no son válidos con a. que es algo que estaba planeando hacer más tarde para emular el estilo del editor hexadecimal.

Si hay otras sugerencias, me alegraría saber de ellas, pero creo que puedo crear una solución que sea más rápida que la original y que haga lo que necesito al mismo tiempo.

¿Fue útil?

Solución

Usé PAnsiChar en mi ejemplo por una razón. Parecía que OutputLength se medía en bytes, no en caracteres, así que me aseguré de usar un tipo cuya longitud siempre se mide en bytes. También notará que mostré la declaración de OutputString como un AnsiString .

Sin embargo, dado que el control de edición almacenó Unicode, habrá una conversión entre AnsiString y UnicodeString . Eso tendrá en cuenta la página de códigos actual del sistema, pero eso probablemente no sea lo que desea. Es posible que desee declarar la variable como RawByteString en su lugar. Eso no tendrá ninguna página de códigos asociada, por lo que no habrá conversiones inesperadas.

No use cadenas para almacenar datos binarios. Si está creando lo que equivale a un editor hexadecimal, entonces está trabajando con datos binarios. Es importante recordar eso. Incluso si sus datos binarios suceden consisten principalmente en bytes que se pueden interpretar como texto, no puede tratar los datos como texto o se encontrará exactamente con los problemas que está viendo & # 8212 ; personajes que no aparecen como se esperaba. Si obtiene un montón de bytes de su dispositivo SCSI, guárdelos en una matriz de bytes, no en caracteres.

En los editores hexadecimales, notará que siempre muestran los valores hexadecimales de los bytes. Pueden mostrar esos bytes interpretados como caracteres, pero eso es secundario, y generalmente solo muestran los bytes que pueden representar caracteres ASCII; no intentan ponerse demasiado elegantes con la pantalla básica. Los editores hexadecimales bueno también ofrecerán mostrar los datos interpretados como caracteres anchos. Esto ayuda a la depuración porque el usuario puede ver los mismos datos de varias maneras. Pero son solo vistas de los datos. En realidad no están cambiando el contenido binario de los datos.

Otros consejos

Algunos comentarios:

  1. Tu pregunta no está muy clara. ¿Qué es exactamente lo que quieres hacer?
  2. Su pregunta parece terrible, por favor revise su texto con un corrector ortográfico.
  3. La pregunta a la que se refiere es esta: Delphi que accede a los datos desde una matriz dinámica que se rellena desde un puntero sin tipo
  4. Por favor, proporcione una muestra de código completo de su función como lo hizo en su pregunta anterior, quiero saber si implementó la sugerencia de Rob Kennedy o el código que se dio en la siguiente respuesta (esperemos que no :))
  5. Hasta donde entiendo su pregunta: está enviando una consulta a su dispositivo SCSI y obtiene una matriz de bytes que almacena en la variable OutputData. Después de eso, desea mostrar sus datos al usuario. Entonces, su verdadera pregunta es: ¿Cómo mostrar una matriz de bytes al usuario?
  6. Inicie sesión como el mismo usuario y no cree una cuenta para cada nueva pregunta. De esa forma, podemos rastrear su historial de preguntas y descubrir qué quiere decir con 'obtener asesoramiento'.

Algunos supuestos y sugerencias si tengo razón sobre el verdadero significado de su pregunta:

  1. Mostrar sus datos como una cadena hexadecimal no dará ningún problema
  2. Mostrar sus datos en un campo Memo normal le da problemas, aunque una cadena Delphi puede contener cualquier carácter, incluidos 0 bytes, mostrarlos le dará problemas. Un TMemo, por ejemplo, mostrará sus datos hasta el primer byte 0. Lo que tiene que hacer (y dio la respuesta usted mismo) es reemplazar los caracteres no visibles con un muñeco. Después de eso, puede mostrar sus datos en un TMemo. En realidad, todos los visores hexadecimales hacen lo mismo, los caracteres que no se pueden imprimir se mostrarán como un punto.

Cuando filtre caracteres no visibles ... Probablemente necesite decidir qué hacer con un par de ellos, como # 9 (Tab), # 10 (LF), # 11 (Tabulador vertical), # 12 (FF-o nueva página), # 13 (CR)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top