-
Блин. В одном месте забыл поменять. Изменил. Теперь все ок.
Только есть проблема с приёмом сообщения клиентом.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]
И разве это проблема -
> 3. тоже проверь, если принимающий буфер не требуется то
> и создавать OutStream не нужно
А куда тогда результат то девать? -
Что в этом случае передавать в качестве второго параметра? 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. -
Спасибо. Разобрался со всем этим.
Для использования с формами сделал наследника от 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; -
Ах, да. Забыл. TPipeServer - это как TSimpleObject из примера :)