2015-02-11 5 views
-1

Я не программист Delphi, и мне нужно сделать некоторые изменения в программе и перекомпилировать. Но проблема в том, что я не могу повторно скомпилировать исходный код, который у меня уже есть. Я проследил эту проблему, и, похоже, из-за Delphi XE7 с использованием Indy 10 вместо Indy 9. И так как TIdPeerThread не существует в Indy 10, я получаю ошибки.Delphi XE7, проблема с компиляцией, необъявленный идентификатор: 'TIdPeerThread'

Я буду очень признателен, если вы поможете мне изменить код, чтобы он совместим с Indy 10, и я могу перекомпилировать его в Delphi XE7.

library TCPServer; 

uses 
    SysUtils, 
    Classes, 
    Forms, 
    IdTCPServer, 
    IdTCPClient, 
    Dialogs; 

{$R *.res} 

const 
    nInputs = 60; 
    nOutputs = 60; 
type 
    ts = array[0..255] of char; 
    array_in = array[1..nInputs] of single; 
    array_out = array[1..nOutputs] of single; 
    Thelper = class 
    IdTCPServer: TIdTCPServer; 
    procedure IdTCPServer1Execute(AThread: TIdPeerThread); 
    procedure IdTCPServer1Connect(AThread: TIdPeerThread); 
    procedure IdTCPServer1DisConnect(AThread: TIdPeerThread); 
    end; 

var 
    helper: Thelper; 

    server_to_be_send: string = ''; 
    server_lastread: string = ''; 

    firsttimecall : boolean = true; 

    inputvector_delay : array_in; 
    outputvector_delay : array_out; 
    time_old : single = -1.0; 

procedure Thelper.IdTCPServer1Connect(AThread: TIdPeerThread); 
begin 
    try 
    Write('Connect from '+AThread.Connection.Socket.Binding.IP+':'+IntToStr(AThread.Connection.Socket.Binding.Port)); 
    WriteLn(' (peer '+AThread.Connection.Socket.Binding.PeerIP+':'+IntToStr(AThread.Connection.Socket.Binding.PeerPort)+')'); 
    except 
    end; 
end; 

procedure Thelper.IdTCPServer1DisConnect(AThread: TIdPeerThread); 
begin 
    try 
    Write('Disconnect to '+AThread.Connection.Socket.Binding.IP+':'+IntToStr(AThread.Connection.Socket.Binding.Port)); 
    WriteLn(' (peer '+AThread.Connection.Socket.Binding.PeerIP+':'+IntToStr(AThread.Connection.Socket.Binding.PeerPort)+')'); 
    except 
    end; 
end; 

procedure Thelper.IdTCPServer1Execute(AThread: TIdPeerThread); 
var 
    ii : Integer; 
begin 
    IdTCPServer.OnExecute := nil; 
    while true do 
    begin 
    Application.ProcessMessages(); 
    if (server_to_be_send<>'') then 
    begin 
     AThread.Connection.WriteLn(server_to_be_send); 
     server_to_be_send := ''; 
     server_lastread := AThread.Connection.ReadLn('*',5000); 
     if server_lastread='' then 
     for ii:=1 to nInputs do server_lastread := server_lastread + '0;'; 
    end; 
    end; 
end; 

Procedure tcplink(na:integer;var inputvector : array_in; 
        nb:integer;var outputvector: array_out);stdcall; 
var 
    i : Integer; 
    st : string; 
begin 

    // Ensure English locale decimal separator symbol 
    DecimalSeparator := '.'; 

    if firsttimecall then 
    begin 
    firsttimecall := false; 

    helper := Thelper.Create(); 
    helper.IdTCPServer := TIdTCPServer.Create(nil); 
    helper.IdTCPServer.OnExecute := helper.IdTCPServer1Execute; 
    helper.IdTCPServer.OnConnect := helper.IdTCPServer1Connect; 
    helper.IdTCPServer.OnDisconnect := helper.IdTCPServer1DisConnect; 
    helper.IdTCPServer.DefaultPort := 1239; 
    try 
     helper.IdTCPServer.Active := true; 
     if helper.IdTCPServer.Active then 
     Writeln('TCP/IP host ready, default port: '+IntToStr(helper.IdTCPServer.DefaultPort)); 
    except 
     Writeln('*** Could not start TCP/IP server ***'); 
    end; 
    end; 

    st := IntToStr(nInputs)+';'; for i:=1 to nInputs do st := st + FloatToStr(inputvector[i])+';'; 
    server_lastread := ''; 
    server_to_be_send := st; 

    while (server_lastread='') do Application.ProcessMessages(); 

    st := server_lastread; 
    server_lastread := ''; 

    for i:=1 to nOutputs do 
    begin 
    if Length(st) < 1 then 
    begin 
     outputvector[i] := 0; 
    end 
    else 
    begin 
     outputvector[i] := StrToFloat(copy(st,1,AnsiPos(';',st)-1)); 
     st := copy(st,AnsiPos(';',st)+1,MaxInt); 
    end; 
    end; 
end; 

// Only call tcplink when time has changed 
Procedure tcplink_delay(na:integer;var inputvector : array_in; 
        nb:integer;var outputvector: array_out);stdcall; 
var 
    i : Integer; 
begin 
    if inputvector[1] > time_old then 
    begin 
    tcplink(na, inputvector_delay, nb, outputvector_delay); 
    time_old := inputvector[1]; 
    end; 

    for i :=1 to nInputs do inputvector_delay[i] := inputvector[i]; 
    for i :=1 to nOutputs do outputvector[i] := outputvector_delay[i]; 

end; 

Procedure tcplink_init(var string256:ts; length:integer);stdcall; 
var 
    init_str : string[255]; 
    onPos : Integer; 
begin 
    init_str:=strpas(string256); 
    // Crop trailing blanks 
    onPos := AnsiPos(' ', init_str); 
    SetLength(init_str, onPos-1); 

    if firsttimecall then 
    begin 
    firsttimecall := false; 

    helper := Thelper.Create(); 
    helper.IdTCPServer := TIdTCPServer.Create(nil); 
    helper.IdTCPServer.OnExecute := helper.IdTCPServer1Execute; 
    helper.IdTCPServer.OnConnect := helper.IdTCPServer1Connect; 
    helper.IdTCPServer.OnDisconnect := helper.IdTCPServer1DisConnect; 
    helper.IdTCPServer.DefaultPort := StrToInt(init_str); 

    try 
     helper.IdTCPServer.Active := true; 
     if helper.IdTCPServer.Active then 

     Writeln('TCP/IP host ready, selected port: '+IntToStr(helper.IdTCPServer.DefaultPort)); 
    except 
     Writeln('*** Could not start TCP/IP server ***'); 
    end; 
    end; 

end; 

Procedure tcplink_delay_init(var string256:ts; length:integer);stdcall; 

begin 
    tcplink_init(string256, length); 
end; 

exports 
    tcplink, tcplink_delay, tcplink_init, tcplink_delay_init; 

begin 
end. 
+2

Если вы знаете, что это причина [это, вероятно, даст вам решение] (https://www.google.com/search?q=+ Indy + 10 + 9 + TIdPeerThread) –

+0

Хорошо, спасибо за быстрый ответ! Я уже пробовал это :) Я фактически переключился с 'TIdPeerThread' на' TIdContext' и использовал 'AContext' вместо' AThread' в коде. Мне также пришлось изменить 'AThread.Connection.WriteLn' на' AContext.Connection.iohandler.WriteLn'. Теперь код компилируется, но не работает! Любая помощь здесь очень ценится! – Mahmood

+0

Просьба описать, что «не работает». Какие ошибки? Что вы видите в отладчике для возвращаемых значений? Возможно, вы не являетесь программистом Delphi, но вам нужно будет изучить IDE, потому что мы не можем отлаживать вас ;-) Это может также помочь, если вы отредактируете свой вопрос и внесите в него измененные части Indy10 рядом с Indy9. –

ответ

1

Как уже отмечалось, исходный код был написан для Indy 9, поэтому он должен быть обновлен до Indy 10.

Он также, как представляется, была написана для версии до Юникода Delphi. ts представляет собой массив Char, который является AnsiChar в Delphi 2007 и ранее, и WideChar в Delphi 2009 и более поздних версиях. И Indy 9 не поддерживает Unicode-версии Delphi. Поэтому я бы предположил, что Char в этом случае должен быть AnsiChar.

Есть также некоторые небольшие логические проблемы.

Вот версия Indy 10, с некоторыми дополнительными исправлениями/ухищрениями:

library TCPServer; 

uses 
    SysUtils, 
    Classes, 
    Forms, 
    IdContext, 
    IdTCPServer, 
    Dialogs; 

{$R *.res} 

const 
    nInputs = 60; 
    nOutputs = 60; 

type 
    ts = array[0..255] of AnsiChar; 
    array_in = array[1..nInputs] of Single; 
    array_out = array[1..nOutputs] of Single; 

    Thelper = class 
    IdTCPServer: TIdTCPServer; 
    destructor Destroy; override; 
    procedure IdTCPServer1Execute(AContext: TIdContext); 
    procedure IdTCPServer1Connect(AContext: TIdContext); 
    procedure IdTCPServer1DisConnect(AContext: TIdContext); 
    end; 

var 
    helper: Thelper = nil; 

    server_to_be_send: string = ''; 
    server_lastread: string = ''; 

    inputvector_delay : array_in; 
    outputvector_delay : array_out; 
    time_old : single = -1.0; 

destructor Thelper.Destroy; 
begin 
    IdTCPServer.Active := false; 
    IdTCPServer.Free; 
    inherited; 
end; 

procedure Thelper.IdTCPServer1Connect(AContext: TIdContext); 
var 
    s: string; 
begin 
    s := Format('Connect on %s:%d (peer %s:%d)', [AContext.Binding.IP, AContext.Binding.Port, AContext.Binding.PeerIP, AContext.Binding.PeerPort]); 
    WriteLn(s); 
end; 

procedure Thelper.IdTCPServer1DisConnect(AContext: TIdContext); 
var 
    s: string; 
begin 
    s := Format('Disconnect from %s:%d (peer %s:%d)', [AContext.Binding.IP, AContext.Binding.Port, AContext.Binding.PeerIP, AContext.Binding.PeerPort]); 
    WriteLn(s); 
end; 

procedure Thelper.IdTCPServer1Execute(AContext: TIdContext); 
var 
    ii : Integer; 
    s : string; 
begin 
    if (server_to_be_send <> '') then 
    begin 
    try 
     AContext.Connection.IOHandler.WriteLn(server_to_be_send); 
    finally 
     server_to_be_send := ''; 
    end; 
    s := AContext.Connection.IOHandler.ReadLn('*', 5000); 
    if s = '' then 
    begin 
     for ii := 1 to nInputs do 
     s := s + '0;'; 
    end; 
    server_lastread := s; 
    end else begin 
    Sleep(10); 
    end; 
end; 

procedure tcplink(na: Integer; var inputvector: array_in; 
        nb: Integer; var outputvector: array_out); stdcall; 
var 
    i : Integer; 
    st : string; 
    t: Cardinal; 
begin 
    if helper = nil then 
    begin 
    helper := Thelper.Create; 
    helper.IdTCPServer := TIdTCPServer.Create(nil); 
    helper.IdTCPServer.OnExecute := helper.IdTCPServer1Execute; 
    helper.IdTCPServer.OnConnect := helper.IdTCPServer1Connect; 
    helper.IdTCPServer.OnDisconnect := helper.IdTCPServer1DisConnect; 
    helper.IdTCPServer.DefaultPort := 1239; 
    helper.IdTCPServer.MaxConnections := 1; 
    end; 
    if not helper.IdTCPServer.Active then 
    try 
    helper.IdTCPServer.Active := true; 
    Writeln('TCP/IP host ready, default port: '+IntToStr(helper.IdTCPServer.DefaultPort)); 
    except 
    Writeln('*** Could not start TCP/IP server ***'); 
    Exit; 
    end; 

    st := IntToStr(nInputs)+';'; 
    for i:=1 to nInputs do st := st + FloatToStr(inputvector[i])+';'; 
    server_lastread := ''; 
    server_to_be_send := st; 

    t := Ticks; 
    while (server_lastread = '') and (GetTickDiff(t, Ticks) < 10000) do 
    Application.ProcessMessages; 

    st := server_lastread; 
    server_lastread := ''; 

    for I := 1 to nOutputs do 
    begin 
    if Length(st) < 1 then begin 
     outputvector[i] := 0; 
    end else 
    begin 
     outputvector[i] := StrToFloat(Copy(st,1,Pos(';',st)-1)); 
     st := Copy(st,Pos(';',st)+1,MaxInt); 
    end; 
    end; 
end; 

// Only call tcplink when time has changed 
procedure tcplink_delay(na: Integer; var inputvector : array_in; 
         nb: Integer; var outputvector: array_out); stdcall; 
var 
    i : Integer; 
begin 
    if inputvector[1] > time_old then 
    begin 
    tcplink(na, inputvector_delay, nb, outputvector_delay); 
    time_old := inputvector[1]; 
    end; 

    for i :=1 to nInputs do inputvector_delay[i] := inputvector[i]; 
    for i :=1 to nOutputs do outputvector[i] := outputvector_delay[i]; 
end; 

procedure tcplink_init(var string256: ts; length: Integer); stdcall; 
var 
    init_str : string; 
    onPos : Integer; 
begin 
    init_str := strpas(string256); 
    // Crop trailing blanks 
    onPos := Pos(' ', init_str); 
    SetLength(init_str, onPos-1); 

    if helper = nil then 
    begin 
    helper := Thelper.Create; 
    helper.IdTCPServer := TIdTCPServer.Create(nil); 
    helper.IdTCPServer.OnExecute := helper.IdTCPServer1Execute; 
    helper.IdTCPServer.OnConnect := helper.IdTCPServer1Connect; 
    helper.IdTCPServer.OnDisconnect := helper.IdTCPServer1DisConnect; 
    helper.IdTCPServer.MaxConnections := 1; 
    end; 
    if not helper.IdTCPServer.Active then 
    try 
    helper.IdTCPServer.DefaultPort := StrToInt(init_str); 
    helper.IdTCPServer.Active := true; 
    Writeln('TCP/IP host ready, selected port: '+IntToStr(helper.IdTCPServer.DefaultPort)); 
    except 
    Writeln('*** Could not start TCP/IP server ***'); 
    Exit; 
    end; 
end; 

procedure tcplink_delay_init(var string256: ts; length: Integer); stdcall; 
begin 
    tcplink_init(string256, length); 
end; 

procedure tcplink_cleanup; stdcall; 
begin 
    FreeAndNil(helper); 
end; 

exports 
    tcplink, tcplink_delay, tcplink_init, tcplink_delay_init, tcplink_cleanup; 

begin 
    // Ensure English locale decimal separator symbol 
    FormatSettings.DecimalSeparator := '.'; 
end. 

Это, как говорится, так как исходный код, как представляется, предназначен для одного соединения TCP в то время, и tcplink() посылает команды и ждет ответа, этот код, вероятно, может быть переписан для использования TIdSimpleServer вместо TIdTCPServer. В отличие от TIdTCPServer, TIdSimpleServer не является многопоточным компонентом, поэтому он может быть более автономным и линейным: дождаться соединения, отправить команду, прочитать ответ, сделать. Нет необходимости в глобальных строковых переменных, обработчиках событий, занятых ожиданиях и т. Д.

+0

Отлично! Большое спасибо Реми! Оно работает! – Mahmood

+0

Тогда, пожалуйста, отметьте ответ, как принято. –

+0

Ошибка новичка! :) – Mahmood

 Смежные вопросы

  • Нет связанных вопросов^_^