-
В delphi 2009 тип строк по умолчанию юникоидный, но попытки привести полученную строку от TServerSocket.ReceiveText к нормальному виду пока никчекму не привели... Кто сталкивался с этой траблой - как решить?
-
"Трабла" в том, что передатчик посылает отнюдь не юникод. Бессмысленно трактовать юникодом то что им на самом деле не является.
-
так как правильно принять?
-
ReceiveBuf
-
Кстати а как пробовал, где код?
-
из всех вариантов наиболее приближенный к ожидаемому результату так:
var
sReceiveText: String;
...
sReceiveText:=PAnsiChar(Socket.ReceiveText);
...
хотя предпологаю что так не совсем правильно и вместо пустых строк символ 's', чего явно не должно быть... Иногда при таком варианте в sReceiveText присутствуют куски "мусора". По сути вызов Socket.ReceiveText и так реализован через ReceiveBuf, вот его реализация:
function TCustomWinSocket.ReceiveText: string;
begin
SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));
SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
end;
никак не доганю что не так?
-
> чего явно не должно быть
Начнем с того - а что на самом деле должно быть ? Что конкретно ты ожидал увидеть в строке sReceiveText ? И какими средствами ты разглядывал содержимое этой строки - под отладчиком или каким-нить ShowMessage() ?
-
1. Проект скомпелированный на Delphi 2007 работает как надо, т.е. в sReceiveText получаю строку в нормальном виде ожидаемого формата, на Delphi 2009 эта строка приходет в виде ???????????<вагон всякого мусора> 2. Конкретно то что мне отправляют если я Вас правильно понял, а отправляют мне строгоотформатированное текстовое сообщение (SIP протокол). 3. рассматривал под отладчиком...
-
> никак не доганю что не так?
Должно быть function TCustomWinSocket.ReceiveText: AnsiString;
-
> 3. рассматривал под отладчиком
Отладчик не показывает "вопросов", если ты им правильно пользуешься. Покажи hex-дамп строки..
-
Можно написать так
> function TCustomWinSocket.AnsiReceiveText: AnsiString; > begin > SetLength(Result, ReceiveBuf(Pointer(nil)^, -1)); > SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result))); > > end;
Поскольку кроме ошибки с типом, также еще и SetLenght неверен, итого в функии правильны только две строки, это BEGIN и END и таких мест множество, практически в каждой сетевой функции, если используются строки. Эта же проблема и с рядом DB библиотек, точно также безответсвенно подошли и там. Хотя проводили очень долгую компанию по переводу проектов пользователей под Юникод, а сами такого натворили.
-
> function TCustomWinSocket.ReceiveText: AnsiString
так вот у меня function TCustomWinSocket.ReceiveText: String на сколько я понял это разработчики так спешили перейти на юникод что накосячили в TCustomWinSocket.
-
Это я предлагаю написать свою функцию, что бы не трогать генофонд.
Не знаю связано ли это с спешкой или нет, они просто не тестировали и на Инглише проблема особо не заметна.
Вместо ReceiveText можно пользоваться ReceiveBuf
-
> ReceiveBuf(Pointer(Result)^
Да, косяк именно в случае, когда Result является WideString. Потому и [3]
-
> что бы не трогать генофонд
Думаю, что его можно не трогать, если воспользоваться рантайм-пакетом scktcomp - вряд ли его перекомпиляли. Т.е. внутри него по-прежнему живут анси-строки
-
Думаешь, что они и там устроили пакость? Это же убийство, если в пакетах Ansi, а в dcu Unicode Не думаю, просто они не стали трогать, как было написано string так и оставили, не меняя. А пакеты тоже перекомпилировали.
-
> Думаешь, что они и там устроили пакость?
Все может быть ..
В принципе ты прав - в ситуации, когда разбираться с этой чехардой нет времени и/или неохота, написать свою функцию будет простейшим и лучшим решением.
-
TServerSocket это компонент из Д7 вроде бы?
-
Спасибо в очередной раз! переписывать метод не стал т.к. используется в только одном месте, траблу решил так:
var
sReceiveText: String;
...
SetLength(sReceiveText, Socket.ReceiveBuf(Pointer(nil)^, -1));
SetLength(sReceiveText, Socket.ReceiveBuf(Pointer(sReceiveText)^, Length(sReceiveText)));
...
далее работаем со строкой sReceiveText как обычно. Странно что эта ошибка даже в последних обновлениях на BDS 2009 не исправлена... > Поскольку кроме ошибки с типом, также еще и SetLenght неверен, > итого в функии правильны только две строки, это BEGIN и > END > и таких мест множество, практически в каждой сетевой функции, > если используются строки. Эта же проблема и с рядом DB > библиотек, точно также безответсвенно подошли и там.
самое страшное что это еще может много где всплыть...
-
> var > sReceiveText: String;
Да почему же опять String, а не AnsiString ?
-
т.е. теперь про String вообще нужно забыть?
-
> > var > > sReceiveText: String;
это я скопипастил так, там естественно AnsiString...
-
> теперь про String вообще нужно забыть?
В данном контексте String если и можно использовать, то совсем не так - ты в этом убедился, уведев "вопросы".
-
> d@vinchi (10.09.2009 17:41:20) [20]
Строки они разные бывают и они разные все поддержаны, включая utf-8
-
Я бы вот так написал (работает)
var sReceiveText: AnsiString; ... SetLength(sReceiveText, Socket.ReceiveLength()); SetLength(sReceiveText, Socket.ReceiveBuf(Pointer(sReceiveText)^, Length(sReceiveText)));
Или под Билдером AnsiString _Str;
_Str.SetLength(Socket->ReceiveLength()); Socket->ReceiveBuf(_Str.c_str(), _Str.Length()); RichEdit1->Lines->Add(_Str); Эх, не спроста они эти компоненты на палитру по-умолчанию не вывели...
|