Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.01.05;
Скачать: CL | DM;

Вниз

Вопрос о типе PChar.   Найти похожие ветки 

 
Beginner ©   (2003-12-21 12:40) [0]

Имеется нижеследующая процедура:

procedure TClientSocket.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Count: Integer;
LocalBuffer: PChar;
begin
Count := Socket.ReceiveLength;
GetMem(LocalBuffer, Count + 1);
Socket.ReceiveBuf(LocalBuffer^, Count);
_Buffer := LocalBuffer;
FreeMem(LocalBuffer);
end;

Не могу понять - почему
_Buffer := LocalBuffer;
а не
_Buffer := LocalBuffer^; ?!!!
Поясните, пожалуйста, неграмотному :-(


 
jack128 ©   (2003-12-21 12:56) [1]

Для начала, какой тип имеет _Buffer ? string?
И чего бы добился такой записью
> _Buffer := LocalBuffer^;
localBuffer^ - это символ, а не строка.


 
Digitman ©   (2003-12-21 13:13) [2]


> Не могу понять - почему
> _Buffer := LocalBuffer;
> а не
> _Buffer := LocalBuffer^; ?!!!


ни так ни так не будет правильно
тем паче - с учетом следующей же строчки FreeMem(LocalBuffer);

я бы посоветовал сделать так :

procedure TClientSocket.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Count: Integer;
LocalBuffer: PChar;
begin
Count := Socket.ReceiveLength;
if Count = 0 then Exit;
GetMem(LocalBuffer, Count);
try
Count := Socket.ReceiveBuf(LocalBuffer^, Count);
MemStream.WriteBuffer(LocalBuffer^, Count);
finally
FreeMem(LocalBuffer);
end;
end;


 
jack128 ©   (2003-12-21 13:59) [3]


> Digitman © (21.12.03 13:13) [2]

Разве? Вроде при таком присвоении String := Pchar не происходит копирование строки?
По крайней мере такой код работает нормально
var
Buf: PChar;
Str: string;
begin
GetMem(Buf, 10);
try
FillChar(Buf^, 9, "1");
Str := Buf;
finally
FreeMem(Buf);
end;
Str := Str + "1"; // Для перераспределения памяти
Caption := Str;
end;


 
jack128 ©   (2003-12-21 14:05) [4]


> Вроде при таком присвоении String := Pchar не происходит
> копирование строки?
Читать как:
Вроде при таком присвоении String := Pchar происходит
копирование строки!


 
Beginner ©   (2003-12-21 14:13) [5]


> Digitman
Что по этому поводу скажет признанный авторитет?


 
Anatoly Podgoretsky ©   (2003-12-21 14:17) [6]

А ничего, пока ты не скажешь, что такое _Buffer


 
Digitman ©   (2003-12-21 14:25) [7]


> Beginner


во-первых, см. Anatoly Podgoretsky © (21.12.03 14:17) [6]

во-вторых, на кой черт вообще нужен некий лок.буфер, если у тебя нет ни намека на накопительный буфер ?


 
Beginner ©   (2003-12-21 14:25) [8]

Прошу прощения:
_Buffer: String;


 
jack128 ©   (2003-12-21 14:25) [9]

Вообще мой код роботает по случайности :-)
нужно Buf := AllocMem(10);

> Beginner
Если ты знаешь asm, то можешь сам ответить на мой вопрос просмотрев исходники System._LStrFromPChar и далее.


 
jack128 ©   (2003-12-21 14:28) [10]


> Digitman ©
Ну не уходите ответа ;-) Мы обсуждаем технич сторону дела, а н логику программы Beginner"а. Так как насчет

> jack128 © (21.12.03 13:59) [3]


 
Digitman ©   (2003-12-21 14:28) [11]


> Прошу прощения:
> _Buffer: String;


ну и каков смысл ? в двух буферах одного и того же назначения ?

в примере, который я привел, MemStream - накопительный буфер.

Это - очередь принимаемых данных. В голову ее идет запись в обработчике события приема из гнезда, а из хвоста ее данные могут быть считаны в любой момент времени любой процедурой, которая, собственно, и анализирует принимаемый поток данных


 
Digitman ©   (2003-12-21 14:31) [12]


> jack128 © (21.12.03 14:28) [10]
>
> Ну не уходите ответа


на тот момент не было известно [8]

но если ты настаиваешь, то по факту [8] насчет копирования, происходящем при AnsiStringVar = AnsiString(PCharData), ничего не имею против


 
Beginner ©   (2003-12-21 14:32) [13]

Всё это очень хорошо, на как же всё-таки насчёт:
> Не могу понять - почему
> _Buffer := LocalBuffer;
> а не
> _Buffer := LocalBuffer^; ?!!!


 
Beginner ©   (2003-12-21 14:34) [14]

Уважаемые Мастера, меня не интересует конкретное применение.
Я хочу принципиально решить этот вопрос.


 
MBo ©   (2003-12-21 14:36) [15]

>Beginner
подумай, какой тип данных дает LocalBuffer^


 
Digitman ©   (2003-12-21 14:37) [16]


> меня не интересует конкретное применение


а на кой шут ты тогда приплел сюда гнезда ?)


 
Anatoly Podgoretsky ©   (2003-12-21 14:44) [17]

Абсолютно лишнее и не нужное LocalBuffer, со всеми операциями, string полностью совместим PChar


 
Beginner ©   (2003-12-21 14:48) [18]


> MBo
Думаю, что String.


> Digitman
Над этим работаю, вот и приплёл. Разные переменные необходимы для дальнейшей обработки.


 
Digitman ©   (2003-12-21 14:50) [19]


> > Не могу понять - почему
> > _Buffer := LocalBuffer;
> > а не
> > _Buffer := LocalBuffer^; ?!!!


потому что в 1-м случае в _Buffer: String будут скопированы ВСЕ данные из буфера, на который указывает LocalBuffer, а во 2-м - только 1-й символ из того же буфера


 
MBo ©   (2003-12-21 14:50) [20]

>Думаю, что String.
На каком основании?
А PInteger^ тогда что вернет? :)


 
Beginner ©   (2003-12-21 14:53) [21]


> Digitman
Дошло наконец-то :-)


 
Digitman ©   (2003-12-21 14:55) [22]


> Над этим работаю, вот и приплёл


ну эдак можно и исходники Windows сюда привести) ... на всякий случай)) ... тоже вроде бы как причем))


> Разные переменные необходимы для дальнейшей обработки


если уж тебя приспичело именно String иметь для т.н. "дальнейшей обработки", то в данном контексте все намного проще :

procedure TClientSocket.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Count: Integer;
begin
SetLength(__Buffer, Socket.ReceiveLength);
Count := Socket.ReceiveBuf(__Buffer[1], Length(__Buffer));
SetLength(__Buffer, Count);
end;


 
Beginner ©   (2003-12-21 14:55) [23]


> MBo
Ваша правда, сударь :-) Понял я свой промах.


 
Beginner ©   (2003-12-21 15:00) [24]


> Digitman
Спасибо, сейчас попробую.


 
Digitman ©   (2003-12-21 15:06) [25]


> Спасибо, сейчас попробую


лучше не пробуй.
это - тупиковый путь.
протокол - поточный, рано или поздно получишь этими "граблями" по лбу и придется все переделывать.

для работы в асинхр.режиме следует сразу же предусмотреть в том или ином виде буфер накопления (очередь асинхронно поступающих данных) и извещать некий код, который уже работает с данными в очереди, о том что очередь изменила состояние (в голову очереди добавлены некие новые данные)

иными словами - не меси в одну кучу транспортные алгоритмы и алгоритмы, работающие с данными, получаемыми посредством некоего абстрактного транспорта


 
Beginner ©   (2003-12-21 15:11) [26]


> Digitman
Это я уже сделал :-), т.е. на грабли уже наступил, правда, давно.



Страницы: 1 вся ветка

Текущий архив: 2004.01.05;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.019 c
14-12137
VID
2003-12-15 22:47
2004.01.05
Нужны дрова для GPRS модема Samsung C-100!


14-12143
KILLER_ABV
2003-12-04 11:58
2004.01.05
Нужны скины для компонента SkinEngine


3-11779
Programmer
2003-12-08 11:49
2004.01.05
Как из ConnectionString в ADO вытащить путь к БД


14-12120
sancho
2003-12-08 18:34
2004.01.05
Чем DVD±RW отличается от DVD-RW ?


14-12111
quik
2003-12-14 13:01
2004.01.05
Компоненты