Конференция "WinAPI" » Выбор способа межпроцессного взаимодействия [D7, WinXP]
 
  • krupt © (13.12.12 00:33) [20]
    Блин. В одном месте забыл поменять. Изменил. Теперь все ок.
    Только есть проблема с приёмом сообщения клиентом.
    procedure TForm1.Button1Click(Sender: TObject);
    var
     InString, OutString: AnsiString;
     PipeClient: TFWPipeClient;
     InStream, OutStream: TMemoryStream;
    begin
     InString := Edit1.Text;
     OutString := '';
     try
       PipeClient := TFWPipeClient.Create('.', 'FWIOCompletionPipeServer');
       try
         PipeClient.Active := True;
         InStream := TMemoryStream.Create;
         try
           OutStream := TMemoryStream.Create;
           try
             InStream.Clear;
             InStream.SetSize(Length(InString));
             Memo1.Lines.Add('OutStr = ' + InString);
             Data := Length(InString);
             Memo1.Lines.Add('OutStrLen = ' + IntToStr(Data));
             InStream.WriteBuffer(Pointer(InString)^, Length(InString));
             PipeClient.SendData(InStream, OutStream);
             SetLength(OutString, OutStream.Size);
             OutStream.ReadBuffer(Pointer(OutString)^, OutStream.Size);
             Memo1.Lines.Add('InStrLen = ' + IntToStr(OutStream.Size));
             Memo1.Lines.Add('InStr = ' + OutString);
           finally
             OutStream.Free;
           end;
         finally
           InStream.Free;
         end;
       finally
         PipeClient.Free;
       end;
     except
       on E:Exception do
         Memo1.Lines.Add(E.Classname + ': ' + E.Message);
     end;
    end;



    Получаю обратное на "Edit1":
    InStrLen = 5
    InStr = Ed
  • Германн © (13.12.12 00:53) [21]
    Где-то все-таки юникод остался. Скорее всего.
    В результате в какой-то функции приема/передачи принимается/передается вдвое меньше байт, чем следовало бы.
  • Германн © (13.12.12 01:26) [22]
    Вот что происходит когда строковый тип используется в качестве "простого буфера для функций приема/передачи"!
    Как хорошо всё выглядело когда тип String был простой "паскалевской" строкой. И как плохо с этим в Д2009+.
    Все "привычные" функции приема/передачи имеют параметр, который относится к количеству принятых/переданных байт. В то время как "длина" строки, которая определяется функцией Length и задаётся процедурой SetLength зависит от кодировки и не всегда равна количеству байт занимаемых строкой.
  • Anatoly Podgoretsky © (13.12.12 08:10) [23]
    > Германн  (13.12.2012 01:26:22)  [22]

    И разве это проблема
  • krupt © (13.12.12 11:38) [24]

    > 3. тоже проверь, если принимающий буфер не требуется то
    > и создавать OutStream не нужно

    А куда тогда результат то девать?
  • krupt © (13.12.12 12:59) [25]
    Что в этом случае передавать в качестве второго параметра? nil?
  • Rouse_ © (13.12.12 13:34) [26]
    Проверил - проблема была до кучи и в самом классе (буфера юникодные использовались).
    Забирай обновку, в качестве демки я туда как раз прикрутил передачу строк.
    http://rouse.drkb.ru/network.php#fwiocompletionpipe
  • Германн © (14.12.12 01:56) [27]

    > Rouse_ ©   (13.12.12 13:34) [26]
    >
    > Проверил - проблема была до кучи и в самом классе (буфера
    > юникодные использовались).

    Ну я ж говорил, что где-то все-таки юникод остался. :)
  • Германн © (14.12.12 02:04) [28]

    > Anatoly Podgoretsky ©   (13.12.12 08:10) [23]
    >
    > > Германн  (13.12.2012 01:26:22)  [22]
    >
    > И разве это проблема
    >

    Ну смотри. При переносе кода с 16-ти битной Дельфи на 32-х битную мне достаточно было лишь поставить в проекте опцию {$H-}  и всё работало.
    А вот при переносе с Д2007 на Д2009+ нужно сделать гораздо больше "телодвижений". И больше всего меня смущает то, что написано в доквики:
    In Delphi code, Length returns the number of characters actually used in the string or the number of elements in the array. In C++ code, use the method of the same name on the AnsiString or DynamicArray class.

    S is a string-valued or array-valued expression.

    For single-byte and multibyte strings, Length returns the number of bytes used by the string. Example for UTF-8:

    Writeln(Length(Utf8String('1¢'))); // displays 3

    For Unicode (WideString) strings, Length returns the number of bytes divided by two.
  • krupt © (14.12.12 21:20) [29]
    Спасибо. Разобрался со всем этим.
    Для использования с формами сделал наследника от TThread и переназначил метов Execute:
    procedure TMyThread.Execute;
    var
     PipeServer: TPipeServer;
    begin
     try
       PipeServer := TPipeServer.Create;
       try
         PipeServer.Server.Active := True;
       finally
         PipeServer.Free;
       end;
     except
     end;
    end;

  • krupt © (14.12.12 22:17) [30]
    Ах, да. Забыл. TPipeServer - это как TSimpleObject из примера :)
 
Конференция "WinAPI" » Выбор способа межпроцессного взаимодействия [D7, WinXP]
Есть новые Нет новых   [134430   +2][b:0][p:0.002]