Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
15-1166081020
Roman_ln
2006-12-14 10:23
2007.01.07
не подскажите в реестре в какой папке уст. значки в панели задач


15-1166426041
data
2006-12-18 10:14
2007.01.07
Еще одна спортивная ветка)


2-1166263110
Dmytro
2006-12-16 12:58
2007.01.07
как получить доступ к protrcted свойствам извне?


3-1161529514
diofant
2006-10-22 19:05
2007.01.07
Подключение к серверу приложений


6-1155286255
Exot
2006-08-11 12:50
2007.01.07
Перехват данных





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский