Delphi7 source conversion problem for DelphiXE7

1

I have a certain source code to control the Gertec brand microterminal that was compiled in Delphi7 and everything works fine, when I compile in delphi XE7 some problems occur.

For those who do not know micro terminal is this .

I use the following function to send text to the display:

procedure TFTerminalSys.EnviaMensagem(Mensagem:String;Linha:Integer);
var
    buf: array [0..255] of BYTE;
    limitechar:Integer;
begin
    LimparLinha(Linha);
    PosicionarCursor(Linha,1);
    Try
    // Verifica se há algum terminal selecionado
    if (ListBox1.ItemIndex = -1) then
    begin
        Application.MessageBox('Selecione um terminal.','Display',48)
    end
    else
    begin
        System.AnsiStrings.StrPCopy(@buf,Copy(Mensagem,1,20));

        // Envia o comando de DisplayString para o terminal
        if mt_dispstr(id_selecionado, buf[0]) < 1 then
        begin
            Application.MessageBox('Erro enviando comando.','ERRO',16);
        end;
    end;
    Except
        Application.MessageBox('Preencha corretamento os campos.','Display',48);
    end;
end;

This function was changed, the source came in Delphi7, the only difference was that I had to change the line

"StrPCopy(@buf,Copy(Mensagem,1,20));"

for

"System.AnsiStrings.StrPCopy(@buf,Copy(Mensagem,1,20));"

This change for some reason buga my return data, and if I do not change to "System.AnsiStrings.StrPCopy" my message does not pro pro correctly, only the first character is sent (however if rotate the example that came in Delphi7 without changes everything works correctly).

Finally I do not understand why the function of sending data to the terminal is bouncing the data return. Here is the function I use to return the data coming from the terminal:

procedure TFTerminalSys.HabilitaResposta(Senha:Boolean = False);
var
    buf : array [0..255] of BYTE;
    estado: DWORD;
begin

    // Verifica se há algum terminal selecionado
    if (ListBox1.ItemIndex = -1) then
    begin
        Application.MessageBox('Selecione um terminal.','Display',48)
    end
    else
    begin
        if (Senha) then
        begin
            estado := 1
        end
        else
        begin
            estado := 0;
        end;

        // Envia o comando de EditString para o terminal
        if mt_seteditstring(Id_selecionado,buf[0],1,estado) < 1 then
        begin
            Application.MessageBox('Erro enviando comando.','ERRO',16);
        end;
    end;
end;

Incidentally, it also does not work properly after I compiled it in Delphi XE7, instead of returning the data correctly, it returns what seems to be memory garbage. For example: when I type '222' in the micro terminal it is returned '4þUaE222' (among other strange characters), if it was always a fixed number of garbage I could use a copy and start to get the return from when it ends the garbage characters , but the garbage number is not fixed. What's strange is that the garbage in the return changes if I change the function of sending text to the terminal (the first function I pasted up there). Here is an example:

1st case: Changing the line "StrPCopy(@buf,Copy(Mensagem,1,20));" to "System.AnsiStrings.StrPCopy(@buf,Copy(Mensagem,1,20))" and sending '222' to the terminal

Result: 4þ @ aEÓAi2

2nd case: leaving the line "StrPCopy(@buf,Copy(Mensagem,1,20));" unchanged and sending '222' to the terminal

Result: 4þUaEÓ'% 222

In the second case I get a more stable response, I could use a Copy and cut only the garbage-free part, but remembering that I change the line "StrPCopy(@buf,Copy(Mensagem,1,20));" to "System.AnsiStrings.StrPCopy(@buf,Copy(Mensagem,1,20));" because otherwise the message does not send to the display of the terminal correctly, only the first character is sent, for example "Welcome" would send only "B"

My question is why does this memory garbage appear, and why should I run the Delphi7 version correctly?

    
asked by anonymous 25.07.2017 / 20:58

1 answer

1

The problem is in the function:

System.AnsiStrings.StrPCopy(@buf,Copy(Mensagem,1,20));

This method expects Source (the second parameter) to be of type AnsiString . But notice that you have declared the parameter Mensagem as a String :

procedure TFTerminalSys.EnviaMensagem(Mensagem:String;Linha:Integer);

In newer versions of Delphi, type string is now an alias of UnicodeString . Consequently Mensagem ends up being UnicodeString , causing undefined behavior.

To fix, convert the string explicitly to an AnsiString:

System.AnsiStrings.StrPCopy(@buf, AnsiString(Copy(Mensagem,1,20)));
    
31.07.2017 / 14:21