Возможно проблема в следующем: когда в строку засовываешь пакет, и гдето посередине пакета идет подряд 2 нуля, то паскаль считает это концом строки, забывая про оставшуюся часть.
Когда у меня была такая проблема, то я сначала делал StrToHex и только в хекс виде заносил в стринг. Но можно хранить пакет в массиве байтов, это будет даже лучше.
ПС: темку быстро пробежал глазами, если не правильно понял суть, то ногами не бить
Открою секрет. л2пх тоже написано на делфи %)
делфийской строке - похрен сколько у тебя #0#0 в строке встречается.
ибо там не просто "массив" байт. перед ним еще и структура есть в которой один из параметров - длина строки.
Цитата:
Вот что представляет собой эта область памяти, хранящая экземпляр строки 'abc':
Байты с 1 по 4 Счётчик ссылок равный -1
Байты с 5 по 8 Длина строки равная 3
Байт 9 Символ 'a'
Байт 10 Символ 'b'
Байт 11 Символ 'c'
Байт 12 Символ с кодом 0 (#0)
Для удобства работы с такой структурой, когда строковой переменной присваивается ссылка на эту строку, в переменную заносится адрес не начала этой структуры, а адрес её девятого байта. Т.е. адрес начала реальной строки (прямо как pChar). Для того, что бы приблизиться к реальной жизни, перепишем приведённую структуру:
Смещение Размер Значение Назначение
-8 4 -1 Счётчик ссылок
-4 4 3 Длина строки
0 1 'a'
1 1 'b'
2 1 'c'
3 1 #0
С полем по смещению -8, нам уже должно быть все ясно. Это значение, хранящееся в двойном слове (4 байта), тот самый счетчик, который позволяет оптимизировать хранение одинаковых строк. Значение этого счетчика имеет тип Integer, т.е. может быть отрицательным. На самом деле, используется лишь одно отрицательное значение – "-1", и положительные значения. 0 не используется.
Теперь, обратите внимание на поле, лежащее по смещению -4. Это, четырёхбайтовое значение длинны строки (почти как в ShortString). Думаю, Вы заметили, что размер памяти выделенной под эту строку не имеет избыточности. Т.е. компилятор выделяет под строку минимально необходимое число байт памяти. Это конечно хорошо, но, при попытке "нарастить" строку: s1 := s1 + 'd', компилятору, точнее библиотеке времени исполнения (RTL) придется перераспределить память. Ведь теперь строке требуется больше памяти, аж на целый байт. Для перераспределения памяти нужно знать текущий размер строки. Вероятно, именно для того, что бы не приходилось каждый раз сканировать строку, определяя её размер, разработчики Delphi и включили поле длины, строки в эту структуру. Длина строки, хранится как значение Integer, отсюда и ограничение на максимальный размер таких строк – 2 Гбайт. Надеюсь, мы не скоро упрёмся в это ограничение. Кстати, именно потому, что память под эти строки выделяется динамически, они и получили ещё одно свое название: динамические строки.
Добавлено через 2 минуты
к стати, там очень неплохо описано что происходит с разнообразными типами в памяти при операциями над ними.
Добавлено через 5 минут
а вот собственно практическое подтверждение этому:
delphi Код:
var
Test : string;
len : integer;
begin
test := 'HelloWorld!';
CopyMemory(@len,pointer(integer(test)-4),4);//копируем данные с участка памяти лежащего на 4 байта "левее" чем то куда ссылаеццо указатель на строку в участок памяти по которому лежит переменная lenshowmessage(inttostr(len));//показываем lenend;
__________________
L2Ext - project closed.
Последний раз редактировалось alexteam, 10.07.2010 в 14:28.
Причина: Добавлено сообщение
var
NamesArray : arrayofstring;
panelki : arrayofstring;
procedure Init; //Вызывается при включении скриптаbeginsetlength(NamesArray, 6);
setlength(panelki, 6);
NamesArray[0]:='Glav';
NamesArray[1]:='1';
NamesArray[2]:='2';
NamesArray[3]:='3';
NamesArray[4]:='4';
NamesArray[5]:='EVS';
ClearPackets;
end;
procedure Free; //Вызывается при выключении скриптаbeginend;
procedure Say(msg:string);
begin
buf:=#$4A;
WriteD(0);
WriteD(3);
WriteS('1');
WriteS(msg);
SendToClient;
end;
procedure ClearPackets; //чистим масив с пакетамиvar
i : integer;
beginfor i := 0tolength(NamesArray) - 1do panelki[i] := '';
end;
Function GetArrayIndexByName(name:string):integer; //а это я уже выкладывал.. правда щас модифицировал малех.begin
result := 0;
while(result < length(NamesArray))and(lowercase(name) <> lowercase(NamesArray[result]))doinc(result);
if result = length(NamesArray)then result := -1;
end;
procedure scanpanelki; //ну и имя у функцииvar
ind,i : integer;
b : byte;
begin
ind := GetArrayIndexByName(ConnectName);
if ind >= 0thenbegin
panelki[ind] := '';
i := 1;
while i <= length(pck)do//дети, тут я учу плохому, не стоит так делать ) begin
B := ReadC(i);
if b = 0then
panelki[ind] := panelki[ind] + '00'else
panelki[ind] := panelki[ind] + strtohex(chr(b));
end;
say('сосканил панельку у '+ConnectName+'. '+panelki[ind]);
endelse
say('не нашел имя');
end;
procedure ActPanelki; //и у моей тожеvar
msgg : string;
ind : integer;
begin
msgg := ReadS(2); //читаем чтота
ind := GetArrayIndexByName(ConnectName); //получаем по этому чемуто индекс в массивеif ind >= 0then//если имя существовало в масивеif panelki[ind] <> ''then//и пакет был запомнен ранееbegin//то делаем хз чо
pck := '';
say('я сделаю вам панельку ' + NamesArray[ind]+'.');
buf := hstr(panelki[ind]);
SendToClient;
endelse
say('Не был запомнен пакет для : ' + msgg)//если пакет не бул запомненelse
say('Не нашел имя: ' + msgg); //либо отсутствует имя в массиве с именамиend;
beginif pck = ''thenexit; //при юзаньи старой версии пх эта строчка в большинстве случаях обязательна.if FromServer and(pck[1]=#$45)then scanpanelki;
if FromClient and(pck[1]=#$49)then actpanelki;
end.
__________________
L2Ext - project closed.
Последний раз редактировалось alexteam, 10.07.2010 в 23:06.