![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Dynamic arrays и TStream
Grim © (2004-11-28 01:00:00)Доброго всем времени суток!
У меня возник такой вопрос.
Есть таблица с данными (T), записанная в dynamic array of TActorInfo,
где TActorInfo - рекорд из различного типа данных (Bool, Float, Int).
Таблица пересылается через методы idUDPServer.SendBuffer;
UDPServer.SendBuffer(IPAdress, Port, T[0], SizeOf(TActorInfo)*Length(T));
Теперь на другом конце Я должен получить точно такой же массив Т:
UDPServerUDPRead(Sender: TObject; AData: TStream;ABinding: TIdSocketHandle);
begin
SetLength(T, 2); //ye допустим я знаю сколько записей там
Adata.Read(T, SizeOf(TActorInfo)*2);
end;
После этого обращение к Т вызывает ошибку "память там-то не может быть
считана" (обычная).
Вопрос: что я делаю не так или как это сделать иначе (UDP протокол необходим)?
Суслик (2004-11-28 17:55:00) [21]Появилось время проверить
Такой код дает range check error... при всключенном {$R+}
var
i: array of integer;
d: integer;
begin
move(i[0], d, 4);
end;
Так, что правда никокого compiler magic - это просто не фига не работает :)))
Verg (2004-11-28 17:48:00) [22]
> [8] Игорь Шевченко © (28.11.04 17:40)
> Кстати, поделитесь, кто как выходит из ситуации, когда функция
> требует var-параметра (например, Integer или DWORD), а хочется
> передать nil ?
nil^
Игорь Шевченко (2004-11-28 17:40:00) [23]
> Если pointer(T) = nil, то и T[0] равен nil.
Все правильно. Перадача var-параметра происходит по ссылке (в данном адрес T соответствует адресу T[0]), от этого и сгенерированный код одинаковый.
> ну это уже compiler magic...
Да нет, никаких magic-ов.
Кстати, поделитесь, кто как выходит из ситуации, когда функция требует var-параметра (например, Integer или DWORD), а хочется передать nil ?
Почему возник вопрос - часть функций в Windows.pas описана принимающими var-параметры, хотя по описанию функции (в MSDN) она вполне может принимать nil.
Суслик (2004-11-28 16:18:00) [24]
> [5] GuAV © (28.11.04 16:13)
Честно говоря я не помню, где в документации декларировано, что T[0] = nil если T = nil. Наверное, раз вы говорите, это так. Но мне как-то кажется это не очень хорошо выглядит. Поэтому если я пользуюсь T[0], то всегда проверяю. Спасибо за информацию, теперь буду знать (когда проверю, конечно :)))
Суслик (2004-11-28 16:16:00) [25]
> [5] GuAV © (28.11.04 16:13)
> T[0] равен nil
ну это уже compiler magic...
В дельфи и не такое бывает :)))
GuAV (2004-11-28 16:13:00) [26]Суслик © (28.11.04 14:50) [4]
Hа самом деле контролировать не нужно. Если pointer(T) = nil, то и T[0] равен nil. Более того сгенерированный компилятором код будет одинаковым.
procedure Test(var X);
begin
ShowMessageFmt('%X',[Integer(@X)]);
end;
procedure TForm1.FormCreate(Sender: TObject);
var X: array of Integer;
begin
Test(X[0]); // 0
Test(Pointer(X)^); // 0
end;
Суслик (2004-11-28 14:50:00) [27]
> [3] jack128 © (28.11.04 14:45)
мне как-то не часто приходится менять декларацию указанным способом.
Зато контролировать, чтобы при обращении чере [0] был первый элемент мне доставляет большие неудобства.
jack128 (2004-11-28 14:45:00) [28]Суслик © (28.11.04 13:20) [2]
Кстати, некоторое время назад я отказался от подобного подхода, потому что приходится менять код если изменяешь декларацию со статического массива на динамический и наоборот. Тоже(даже в большей степени) для длинных и коротких строк.
Суслик (2004-11-28 13:20:00) [29]если не ошибаюсь, то еще так можно
Adata.Read(pointer(T)^, SizeOf(TActorInfo)*2);
Опять же, если не ошибаюсь, то так более правильно для пустого массива...
Verg (2004-11-28 13:13:00) [30]
> Adata.Read( T[0],SizeOf(TActorInfo)*2);