Форум: "Основная";
Текущий архив: 2007.01.07;
Скачать: [xml.tar.bz2];
ВнизПреобразование Untyped, что посоветуете? Найти похожие ветки
← →
gosha73 (2006-11-16 01:58) [0]Здравствуйте уважаемые.
Работаю с интерфейсами написанными другими программерами на дельфи. И тут в описании интерфейса вижу метод :procedure OnUniqMessage(Message: Word; const Rec);
Т.е. есть список сообщений, который прилагается к интерфейсу и есть все соответсвующие сообщениям структуры. В зависимости от сообщения в Rec записываются различные структуры, в том числе различные по размеру и членам. Насколько это грамотно и безопасно хочу понять.
На той стороне программеры обрабатывают сообщения таким образом:...
type
TSome1 = record
Val1: Integer;
Str1: WideString;
end;
TSome2 = record
Str1: WideString;
Str2: WideString;
Vis: Boolean;
end;
...
procedure THdlr.OnUniqMessage(Message: Word; const Rec);
var Some1: TSome1;
Some2: TSome2;
...
begin
case Message of
MSG_1: Some1 := TSome1(Rec);
MSG_2: Some2 := TSome2(Rec);
.....
end;
.....
end;
Что посоветуете? Может еще что-то надо проверять прежде чем нетипизированный Rec копировать в разные структуры?
← →
Eraser © (2006-11-16 02:07) [1]> [0] gosha73 (16.11.06 01:58)
мен сильно смущает использование WideString в записях...
← →
gosha73 (2006-11-16 02:07) [2]Ах да, а я отправляю эти сообщения из своей программы через интерфейс таким образом:
....
var Some1: TSome1;
begin
Some1.Val1 := Sender.Tag;
Some1.Str1 := Sender.WideStrCaption;
Hndlr.OnUniqMessage(MSG_1, Some1);
end;
...
Во всех этих примерах всё работает, главное не перепутать сообещния и соответсвующие им структуры, но надежность и стабильность меня сильно беспокоят. Вот и обращаюсь к вам, как к более опытным.
← →
gosha73 (2006-11-16 02:29) [3]Хочу предложить им добавить в метод еще параметр размера передаваемой записи, что-то вроде этого:
procedure OnUniqMessage(Message: Word; const Rec; RecSize: LongInt);
Тогда они бы могли проверять размер записи с полученным, прежде чем преобразовывать нетипизированный параметр в запись.
К примеру так:
procedure THdlr.OnUniqMessage(Message: Word; const Rec; RecSize: LongInt);
var Some1: TSome1;
...
begin
case Message of
MSG_1: begin if (RecSize = SizeOf(TSome1)) then Some1 := TSome1(Rec);end;
.....
end;
.....
end;
Но это не решает проблему, в случае если размеры записей с различными членами совпадают. Наверняка должен быть способ максимально безопасно проверить нетипизированный параметр.
← →
Eraser © (2006-11-16 03:09) [4]> [3] gosha73 (16.11.06 02:29)
1. в данном случае нужно передавать не запись, а указатель на запись.
2. никаких доп. проверок не нужно, ведь есть Message, который должен однозначно пояснять, что находится в структуре.
← →
Anatoly Podgoretsky © (2006-11-16 08:44) [5]> gosha73 (16.11.2006 01:58:00) [0]
Нигде не видать определения MSG_N
Без него нет предмета для разговора.
← →
Anatoly Podgoretsky © (2006-11-16 08:45) [6]> gosha73 (16.11.2006 02:29:03) [3]
А ты не хочешь вывести размер в ShowMessage?
← →
evvcom © (2006-11-16 09:16) [7]> [0] gosha73 (16.11.06 01:58)
> procedure THdlr.OnUniqMessage(Message: Word; const Rec);
> var Some1: TSome1;
> Some2: TSome2;
Я бы написал так:var
Some1: TSome1 absolute Rec;
Some2: TSome2 absolute Rec;
Тогда фигня
> case Message of
> MSG_1: Some1 := TSome1(Rec);
> MSG_2: Some2 := TSome2(Rec);
> .....
> end;
вообще не нужна, уже все присвоено :)
> [3] gosha73 (16.11.06 02:29)
> Хочу предложить им добавить в метод еще параметр размера
> передаваемой записи, что-то вроде этого:
> procedure OnUniqMessage(Message: Word; const Rec; RecSize:
> LongInt);
Обычно, размер добавляют первым членом в записи. Можно, конечно, но имхо, это лишнее. Лишняя проверка, которая все равно на 100% от ошибки программиста не избавит.
> [5] Anatoly Podgoretsky © (16.11.06 08:44)
> Нигде не видать определения MSG_N
Да вроде как и так интуитивно понятно, что это Word-константы.
← →
Anatoly Podgoretsky © (2006-11-16 10:18) [8]> evvcom (16.11.2006 09:16:07) [7]
Интуиция=телепатия
Если это константы, то какая проблема, одназначная идентификация структуры, поскольку это идентификатор и есть.
> Обычно, размер добавляют первым членом в записи
Все таки предлагаю вывести размер первой и второй структуры в диалог.
← →
gosha73 (2006-11-16 10:46) [9]Спасибо за советы. Да действительно, размер можно сделать первым членом записи.
Anatoly Podgoretsky, да это константы, но хочется и одназначную идентификацию обезопасить от любого горе программиста, ошибись который, повлечет собой ошибку доступа памяти в ядре программы.
← →
Сергей М. © (2006-11-16 10:55) [10]
> идентификацию обезопасить от любого горе программиста
От этого спасают объекты, реализующие интерфейсы-наследники IUnknown.
← →
evvcom © (2006-11-16 11:51) [11]> [9] gosha73 (16.11.06 10:46)
> одназначную идентификацию обезопасить от любого горе программиста,
> ошибись который, повлечет собой ошибку доступа памяти в
> ядре программы
Я утверждаю, что на 100% обезопаситься от горе программиста невозможно! Ну и что страшного в том, что получишь AV? По идее это на этапе разработки/тестирования уже должно вылезти. А передача размера структуры тебя не обезопасит, только увеличит размер программы. Что помешает горе-программисту запросить в куче 2 байта, а передать в функцию размер в мегабайт? Ничего. Потому, имхо, это лишнее.
> [8] Anatoly Podgoretsky © (16.11.06 10:18)
> Если это константы, то какая проблема, одназначная идентификация
> структуры, поскольку это идентификатор и есть.
Полностью поддерживаю.
← →
Anatoly Podgoretsky © (2006-11-16 11:52) [12]> gosha73 (16.11.2006 10:46:09) [9]
Одназначную идентификацию обеспечивают только классы или по крайней мере специально сконструированые структуры. Поле структуры с идентификаторов. Передача указателя на что то неизвестное, такой идентификации в принципе не обеспечит.
Так как все таки с размером структур то, проверил?
← →
Anatoly Podgoretsky © (2006-11-16 11:53) [13]> Сергей М. (16.11.2006 10:55:10) [10]
Или это
← →
iva © (2006-11-16 12:36) [14]imho
Я бы попробовал сделать интерфейсный модуль в котором бы описалmyOnUniqMessage(Hndlr:THndlr;Some:TSome1); overload;
myOnUniqMessage(Hndlr:THndlr;Some:TSome2); overload;
myOnUniqMessage(Hndlr:THndlr;Some:TSome3); overload;
myOnUniqMessage(Hndlr:THndlr;Some:TSome4); overload;
....
procedure myOnUniqMessage(Hndlr:THndlr;Some:TSome1);
begin
Hndlr.OnUniqMessage(MSG_1, Some);
end;
procedure myOnUniqMessage(Hndlr:THndlr;Some:TSome2);
begin
Hndlr.OnUniqMessage(MSG_2, Some);
end;
а вызов из программы был бы такимmyOnUniqMessage(Hndlr, Some as TSome2);
← →
gosha73 (2006-11-16 17:27) [15]
> Anatoly Podgoretsky © (16.11.06 11:52) [12]
> Так как все таки с размером структур то, проверил?
Да попробовал. Проверял. Но задумка кмк бесполезна. Обезопаситься максимально можно только с типизацией, как большинство и предложило. Иначе идем поперек правилам дельфи как строготипизированного языка.
Тот, кто придумал такой обработчик сообщений, тот раньше на си программировал, а я как человек не привыкший к таким вольностям в языке насторожился сразу увидев такое "безобразие". В дельфи с нетипизированными параметрами приходится иногда работать, в основном с различными буферами, но чтобы так записи передавать, это я не проходил в жизни еще. Ну теперь прошел.
И вам спасибо Сергей М. и iva.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2007.01.07;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.01 c