Pergunta

Eu estava ficando conselho de Rob Kennedy e um de seus sugestões que aumentaram significativamente a velocidade de um aplicativo que eu estava trabalhando era usar SetString e, em seguida, carregá-lo no componente de VCL que exibia-lo.

Estou usando o Delphi 2009 até agora que PChar é Unicode,

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

Obras e eu mudei para PChar mim, mas desde que os dados que estão sendo movidos nem sempre é Unicode, de facto, a sua geralmente ShortString Dados .... então para o que ele realmente me deu para usar:

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

nada aparece, mas eu verificar no depurador eo texto que normalmente apareceu a maneira que eu fiz isso de construção de 1 caractere em um momento no passado foi na variável.

Curiosamente esta não é a primeira vez que eu corri para esta noite. Porque eu estava tentando chegar a uma outra maneira, tomei parte de seu conselho e, em vez de construir em TCaption um VCL eu construí-lo em uma variável de seqüência e depois copiada-lo, mas quando eu enviá-lo por nada do exibido. Mais uma vez no depurador a variável que os dados é construído em ... tem os dados.

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

A descrição acima não trabalho, mas a maneira lenta antiga de fazer isso funcionou muito bem ....

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

Eu tentei fazer a variável de um ShortString, String e TCaption e nada é exibido. O que eu acho interessante é quando eu construir meus dados hexadecimais da mesma matriz em uma richedit é muito rápido ao fazê-lo dentro de uma edição para os dados de texto é muito muito lento. É por isso que não se preocuparam tentando mudar o código para o richedit como funciona Superfast como ela é.

Editar para adicionar - Eu acho que sorta encontrado o problema, mas eu não tenho nenhuma solução. Se eu editar o valor no depurador para remover qualquer coisa que não pode ser exibida (que pelo velho método usado para simplesmente não exibição ... não falhar), então o que eu tenho esquerda é exibida. Então, se é apenas uma questão de se livrar de bytes que foram transformadas para personagens que são lixo Como posso corrigir isso?

Basicamente, eu tenho dados brutos de entrada de um dispositivo SCSI que está sendo exibido estilo hex-editor. Meu estilo lento original adicionando um caractere de cada vez exibido com sucesso cordas e cadeias de caracteres Unicode que não têm caracteres específicos-Unicode neles. Os métodos mais rápidos, mesmo que trabalhando não exibirá ShortStrings uma maneira e outros de exibição UnicodeStrings maneira costuma que não estão usando não 0-255 caracteres. Eu realmente gosto e poderia usar o aumento de velocidade, mas que isso signifique sacrificar a capacidade de ler a cadeia ... então qual é o ponto no aplicativo?

EDIT3 - Tudo bem agora que eu descobri que 0-31 é o controle de char e 32 e se é válido Eu acho que vou fazer uma tentativa de carvão filtro e substituir aqueles não acumulável com a. que é algo que eu estava pensando em fazer mais tarde ao estilo editor hex imitar.

Se houver quaisquer outras sugestões que eu ficaria feliz em ouvir sobre eles, mas caso contrário, eu acho que eu posso criar uma solução que é mais rápido do que o original e faz o que eu preciso que ele, ao mesmo tempo.

Foi útil?

Solução

Eu costumava PAnsiChar no meu exemplo por uma razão. Parecia OutputLength estava sendo medido em bytes, não caracteres, por isso tenho a certeza de usar um tipo cujo comprimento é sempre medido em bytes. Você também vai notar que eu mostrei a declaração de OutputString como um AnsiString.

Uma vez que o controle de edição armazenados Unicode, porém, haverá uma conversão entre AnsiString e UnicodeString. Isso vai levar a página de código atual do sistema em consideração, mas que provavelmente não é o que você quer. Você pode querer declarar a variável como um RawByteString vez. Isso não terá qualquer página de código associado a ele, de modo que não haverá quaisquer conversões inesperadas.

Não use cordas para armazenar dados binários. Se você está construindo o que equivale a um editor hexadecimal, então você está trabalhando com dados binários. É importante lembrar que. Mesmo que seus dados binários acontece para consistem principalmente de bytes que podem ser interpretadas como texto, você não pode tratar os dados como texto ou você vai correr em exatamente os problemas que você está vendo - personagens que não aparecem como esperado. Se você tem um monte de bytes do dispositivo SCSI, em seguida, armazená-los em um array de bytes, não caracteres.

Em editores hexadecimais, você vai perceber que eles sempre mostram os valores hexadecimais dos bytes. Eles podem mostrar os bytes interpretada como personagens, mas isso é secundário, e eles geralmente mostram apenas os bytes que podem representar caracteres ASCII; eles não tentar obter muito extravagante com a indicação básica. O boa editores hexadecimais irá oferecer para exibir os dados interpretados como caracteres largos também. Isso ajuda na depuração, pois o usuário pode olhar para os mesmos dados de várias maneiras. Mas eles são apenas vistas dos dados. Eles não estão realmente mudando o conteúdo binário dos dados.

Outras dicas

Alguns comentários:

  1. A sua pergunta é muito clara. O que exatamente você quer fazer?
  2. A sua questão lê terrível, por favor, verifique o seu texto com um verificador ortográfico.
  3. A pergunta que você está se referindo é esta: Delphi acessar dados de matriz dinâmica que é preenchida a partir de um ponteiro untyped
  4. Por favor, dar um exemplo de código completo de sua função como você fez na sua pergunta anterior, eu quero saber se você implementou a sugestão de Rob Kennedy ou o código que você se deu em uma resposta seguinte (vamos espero que não :))
  5. No que diz respeito a entendi sua pergunta: Você está enviando uma consulta para o seu dispositivo SCSI e você obter uma matriz de bytes de volta o que você armazena na variável OutputData. Depois que você quer mostrar os seus dados para o usuário. Portanto, sua verdadeira questão é:? Como mostrar uma matriz de bytes para o usuário
  6. Faça login como o mesmo usuário e não criar uma conta para cada nova pergunta. Dessa forma, podemos rastrear o histórico pergunta um pode descobrir o que você quer dizer com 'recebendo conselhos'.

Algumas suposições e sugestões se estou certo sobre o verdadeiro significado da sua pergunta:

  1. Mostrando seus dados como uma string hex não trará quaisquer problemas
  2. Mostrando seus dados em um campo Memo normais lhe dá problemas, embora uma string Delphi pode conter qualquer caractere, incluindo 0 bytes, exibindo-lhe dará problemas. A TMemo por exemplo, vai mostrar seus dados até o primeiro 0 byte. O que você tem a fazer (e você deu a resposta você mesmo), é substituir caracteres não pode ser visualizado com um manequim. Depois que você pode mostrar seus dados em um TMemo. Na verdade, todos os espectadores hexadecimais fazer o mesmo, caracteres que não podem ser impressos será mostrado como um ponto.

Quando você filtrar caracteres não visíveis ... Você provavelmente precisa decidir o que fazer com um par de-los como # 9 (Tab), nº 10 (LF), # 11 (Verticle Tab), # 12 (FF-ou New Page), nº 13 (CR)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top