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

Вниз

Преобразование 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.036 c
4-1155966925
zXm
2006-08-19 09:55
2007.01.07
Перехват API методом исправления таблиц импорта.


15-1166520001
tesseract
2006-12-19 12:20
2007.01.07
к 100-летию Леонида Ильича от керка


15-1166203353
Mozart
2006-12-15 20:22
2007.01.07
Проблема с "оцифровкой VHS"


15-1166455220
dr_craigan
2006-12-18 18:20
2007.01.07
открытие картинок с помощью ...


15-1166293792
Sholah_Weras
2006-12-16 21:29
2007.01.07
А таки хочу в космонавты.