Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.10.16;
Скачать: [xml.tar.bz2];

Вниз

Сравнение двух величин TNotifyEvent   Найти похожие ветки 

 
Andsin   (2005-09-26 12:26) [0]

Привет!
Планирую использовать контейнер для уведомления экземляров классов о событии. Именно экземпляров, а не одного экземпляра. Пытаюсь реализовать так:

procedure Foo.AttachOnReply(AnEvent: TNotifyEvent);
var
 matched: boolean;
 i: integer;
begin
 matched := false;
 for i := 0 to Length(FEvents)-1 do
   if FEvents[i] = AnEvent then matched := true;
 if not matched then
 begin
   i := Length(FEvents);
   SetLength(FEvents, i+1);
   FEvents[i] := AnEvent;
 end;
end;

В строчке if FEvents[i] = AnEvent then matched := true; возникают две одинаковых ошибки:
[Error] foo.pas(221): Not enough actual parameters.
т.е. компилятор пытается вызвать соответствующие методы.
Могу ли я исправить код так, чтобы компилятор проверял равенство указателей на метод класса, вместо вызова?
P.S. Преобразование TNotifyEvent  к типу TMethod, на мой взгляд, не является документированной производителем, поэтому такие варианты не катят...

Спасибо!


 
alex_***   (2005-09-26 12:45) [1]

видимо так надо: if @FEvents[i] = @AnEvent


 
Andsin   (2005-09-26 13:36) [2]

сдается, что нет... так я получу лишь адреса элементов, схожих с TMethod, не более того.


 
Digitman ©   (2005-09-26 13:40) [3]


> Преобразование TNotifyEvent  к типу TMethod, на мой взгляд,
>  не является документированной производителем


это почему же ?

оч даже документирован !

и сам тип в интерф.части описан, и в справке черным по белому сказано :

This type can be used in a type cast of a method pointer to access the code and data parts of the method pointer.


 
Andsin   (2005-09-26 13:51) [4]

Я это видел. Не убедительно как-то... Про procedure of object ни слова.


 
evvcom ©   (2005-09-26 13:58) [5]


> Andsin   (26.09.05 13:51) [4]

Ну как знаешь!
А в FEvents[i] = AnEvent идет именно вызов обработчика AnEvent, а тебе нужны указатели.


 
jack128 ©   (2005-09-26 14:01) [6]

if (TMethod(FEvents[i]).Code = TMethod(AnEvent).Code) and (TMethod(FEvents[i]).Data = TMethod(AnEvent).Data) then ...


 
jack128 ©   (2005-09-26 14:05) [7]

Andsin   (26.09.05 13:51) [4]
Я это видел. Не убедительно как-то... Про procedure of object ни слова.

This type can be used in a type cast of a method pointer to access
То есть связи между "procedure of object" и "method pointer" ты не видешь?? Тогда советую подучить основы языка или терминологии. Либо там, либо там но где ты плаваешь.


 
evvcom ©   (2005-09-26 14:06) [8]


> jack128 ©   (26.09.05 14:01) [6]

лень сейчас проверять, но по-моему любое употребление AnEvent без @ (кроме банального присваивания переменной типа TNotifyEvent) будет восприниматься компилятором как вызов обработчика.


 
GuAV ©   (2005-09-26 14:15) [9]

Andsin   (26.09.05 13:36) [2]
сдается, что нет... так я получу лишь адреса элементов, схожих с TMethod, не более того.


Нифига не нет, [1] верно.

procedure TForm1.FormCreate(Sender: TObject);
var
 E1, E2: TNotifyEvent;
begin
 E1 := FormCreate;
 E2 := FormCreate;
 ShowMessage(IntToStr(SizeOf(@E1))); // output is 8
 ShowMessage(BoolToStr(@E2 = @E1, True)); // output is true
 ShowMessage(BoolToStr(@@E2 = @@E1, True)); // output is false
end;


 
andsin   (2005-09-26 14:44) [10]


> То есть связи между "procedure of object" и "method pointer"
> ты не видешь?? Тогда советую подучить основы языка или терминологии.
>  Либо там, либо там но где ты плаваешь.

слушай, но ведь procedure of object это код, а method pointer это текст в стправке. есть ли в справке что-либо, что бы их связывало, кроме их похожести?
Других методов, кроме использования явного приведения типов нет? ведь можно же проверить на равенство nil, в этом случае компилятор не пытается проверить возвращенное значение...


 
andsin   (2005-09-26 14:51) [11]

авторы [1] и [9], вы абсолютно правы. только надо было мне это в справке показать. вот что я наарыл
f F = MyFunction then ...;

In this case, the occurrence of F results in a function call; the compiler calls the function pointed to by F, then calls the function MyFunction, then compares the results. The rule is that whenever a procedural variable occurs within an expression, it represents a call to the referenced procedure or function. In a case where F references a procedure (which doesn’t return a value), or where F references a function that requires parameters, the statement above causes a compilation error. To compare the procedural value of F with MyFunction, use

if @F = @MyFunction then ...;

@F converts F into an untyped pointer variable that contains an address, and @MyFunction returns the address of MyFunction.
To get the memory address of a procedural variable (rather than the address stored in it), use @@. For example, @@F returns the address of F.

это из справки по оператору @
всем спасибо, вопрос решен.


 
Digitman ©   (2005-09-26 14:51) [12]


> ведь можно же проверить на равенство nil, в этом случае
> компилятор не пытается проверить возвращенное значение


да, можно.
потому что компилятор при этом делает неявное приведение именно к типу TMethod

когда ты объявляешь поле класса/структуры как procedure..of object, компилятор резервирует под это поле область памяти со структурой TMethod.


 
jack128 ©   (2005-09-26 15:11) [13]

andsin   (26.09.05 14:44) [10]
procedure of object это код


Да ??? А всегда думал, что полдобная конструкция используюется при объявлении ТИПА. Переменная этого типа хранит в себе УКАЗАТЕЛЬ на код, а так же Self.


 
jack128 ©   (2005-09-26 15:12) [14]

jack128 ©   (26.09.05 15:11) [13]
А я всегда думал, что подобная конструкция используется


 
Andsin   (2005-09-26 16:03) [15]


> Да ??? А всегда думал, что

если сейчас вы так не думаете, то напрасно. я имелл ввиду, что procedure of object мы пишем в исходниках, а method pointer написано в хелпе. очень хочется найти явное взаимно-однозначное соответствие написанному в исходниках(для обозначения оного я использовал слово код, которое вам почему-то не понравилось) написанному в хелпах. чего и удалось достичь благодаря alex_*** и GuAV.
З.Ы. Заметьте, я не стал придираться к вашей нелепой фразе относительно того, что переменная типа TNotifyEvent содержит Self.


 
evvcom ©   (2005-09-26 20:20) [16]


> слушай, но ведь procedure of object это код, а method pointer
> это текст в стправке

Тоже придирусь. И то, и другое - это текст. Но первый используется в коде для описания типа, а второй является обобщением для первого и еще function of object. А это действительно описано в терминологии, что и советовал jack128 ©   (26.09.05 14:05) [7] подучить.

> Заметьте, я не стал придираться к вашей нелепой фразе относительно
> того, что переменная типа TNotifyEvent содержит Self.

И чем же эта фраза нелепа? Переменная типа TNotifyEvent действительно содержит 2 двойных слова (точно также как и TMethod): адрес обработчика и указатель на объект, в контексте которого будет вызван этот обработчик, т.е. Self.
Вообще, я бы посоветовал тем, кто начинает работать с указателями тем или иным образом, почаще открывать CPU Window и вникать, что и почему.


 
Defunct ©   (2005-09-27 06:17) [17]

ps: Самое правильное решение imho jack128 ©   (26.09.05 14:01) [6]
все остальное от лукавого. Особенно @ - вообще ничего не даст.

Andsin   (26.09.05 16:03) [15]
З.Ы. Заметьте, я не стал придираться к вашей нелепой фразе относительно того, что переменная типа TNotifyEvent содержит Self.

Фраза не так уж нелепа как могло показаться. TMethod( NotifyEvent).data и есть тот самый Self.

> Andsin
> if @F = @MyFunction then
так лучше не делать, т.к. методы разных экземляров так выявить не удастся. С помощью ссылки "@" получите только указатель на метод класса.


 
evvcom ©   (2005-09-27 08:29) [18]


> Фраза не так уж нелепа как могло показаться

неведающему. Не надо всех сюда грести.


 
Lamer@fools.ua ©   (2005-09-27 09:19) [19]

>>Defunct ©   (27.09.05 06:17) [17]

>Фраза не так уж нелепа как могло показаться. TMethod( NotifyEvent).data и есть тот самый Self.

Оне не нелепа. Просто некорректна.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs;

type
 TSomeObj = class(TObject)
 public
   procedure OnFormClick(Sender: TObject);
 end;

 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   FSomeObj: TSomeObj;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

{ TSomeObj }

procedure TSomeObj.OnFormClick(Sender: TObject);
begin
 ShowMessage("Ку!");
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FSomeObj := TSomeObj.Create;
 try
   OnClick := FSomeObj.OnFormClick; // И совсем здесь не Self, а FSomeObj.
 except
   OnClick := nil;
   FreeAndNil(FSomeObj);
   raise;
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 OnClick := nil;
 FreeAndNil(FSomeObj);
end;

end.


 
andsin   (2005-09-27 09:35) [20]


> И чем же эта фраза нелепа? Переменная типа TNotifyEvent
> действительно содержит 2 двойных слова (точно также как
> и TMethod): адрес обработчика и указатель на объект, в контексте
> которого будет вызван этот обработчик, т.е. Self.

Если прочитаете справку по self,  поймете, что это указатель на экземпляр класса, доступный из методов класса. Нелепость в том, что TNotifyEvent будет содержать Self, только в том случае, если из метода какого- либо класса написать примерно следующее

begin
 Form1.OnShow := Self.FormShow;
end;


> Вообще, я бы посоветовал тем, кто начинает работать с указателями
> тем или иным образом, почаще открывать CPU Window и вникать,
>  что и почему.

Да, так можно знаешь до чего довникаться... Нет, справка это единственный источник информации, и по указателям в том числе.

отладка кода на строчке  if @F = @MyFunction then дала отрицательный результат. действительно, содержимое указателя на екземпляр класса не анализируется.
Получается, что без преобразования типов не обойтись, чтоли?


 
andsin   (2005-09-27 09:39) [21]

И вижу, что находится масса людей, которая не вникла в суть вопроса... повторю вопрос:
Существует ли документированный способ сравнения двух величин типа TNotifyEvent. Преобразование к типу TMethod прошу не предлагать.


 
Leonid Troyanovsky ©   (2005-09-27 09:55) [22]


> andsin   (27.09.05 09:39) [21]

> Существует ли документированный способ сравнения двух величин
> типа TNotifyEvent. Преобразование к типу TMethod прошу не
> предлагать.


Экий ты настырный. Проверок типа
 
if (TMethod(Value).Code <> TMethod(OnExecute).Code) or
    (TMethod(Value).Data <> TMethod(OnExecute).Data) then

полная VCL огурцов (еще от царя Гороха).
Чего там еще документировать?
Ну, или попроси разрешения у борландов напрямую.

--
Regards, LVT.

ЗЫ И, вообще, "использовать контейнер для уведомления экземляров классов о событии" мне представляется неудачной задумкой.


 
andsin   (2005-09-27 10:07) [23]


> "использовать контейнер для уведомления экземляров классов
> о событии" мне представляется неудачной задумкой

что-нить лучше подсказать можете?


 
Digitman ©   (2005-09-27 10:28) [24]


> Существует ли документированный способ сравнения двух величин
> типа TNotifyEvent. Преобразование к типу TMethod прошу не
> предлагать


да на здоровье !

if CompareMem(@Event1, @Event2, SizeOf(TNotifyEvent)) then ..

как видишь, никаких преобразований к типу TMethod нет и в помине ..

но суть от этого НЕ изменилась - по прежнему сравнивается содержимое областей памяти, занятых структурами типа TMethod


 
Leonid Troyanovsky ©   (2005-09-27 11:13) [25]


> andsin   (27.09.05 10:07) [23]

> > "использовать контейнер для уведомления экземляров классов
> > о событии" мне представляется неудачной задумкой

> что-нить лучше подсказать можете?


Все уже украдено до нас.
Начиная от уведомлений TControl лежащих на TWinControl
(например, компонентные сообщения),  
и  до COM+ "издатель-подписчик".

--
Regards, LVT.


 
evvcom ©   (2005-09-27 11:21) [26]


> OnClick := FSomeObj.OnFormClick; // И совсем здесь не Self,
>  а FSomeObj.

Это в TForm1.FormCreate здесь действительно не Self. А когда вызовется твой FSomeObj.OnFormClick, там это будет уже Self.

> Да, так можно знаешь до чего довникаться... Нет, справка
> это единственный источник информации

Ну? До чего можно довникаться?
Если справка - единственный источник информации, то чего же ты делаешь на этом форуме?


 
andsin   (2005-09-27 12:19) [27]


> Ну? До чего можно довникаться?

Ответ на этот вопрос предлагаю найти в качестве упражнения.

> Если справка - единственный источник информации, то чего
> же ты делаешь на этом форуме?

Я же писал, ищу документированный способ осуществить сравнение.
Тема закрыта, в общем.


 
Lamer@fools.ua ©   (2005-09-27 13:29) [28]

>>andsin   (27.09.05 12:19) [27]

Читать [3]. До полного просветления.


 
evvcom ©   (2005-09-27 13:55) [29]


> Lamer@fools.ua ©   (27.09.05 13:29) [28]

Думаю, не поможет. Это хронический случай с летальным исходом. :(


 
andsin   (2005-09-27 14:29) [30]

да, вынужден констатировать, что не смотря на наличие правильных ответов в постах людей, вменяемым стоит признать не многих,  Leonid Troyanovsky, например.
Lamer@fools.ua,  evvcom для вас отдельно повторю, что тема закрыта, вопрос понятен, решение получено. вам понятно?


 
Digitman ©   (2005-09-27 14:35) [31]


> andsin   (27.09.05 14:29) [30]


напрасно пальцы гнешь.

если тему закрыл, то "уходя - уходи".

если иначе, то  поостерегись упоминать всуе про "вменяемость". иначе тебе грозит LMD-диагноз


 
andsin   (2005-09-27 15:04) [32]

Digitman, ты еще жив? :)))


 
Digitman ©   (2005-09-27 15:22) [33]


> andsin   (27.09.05 15:04) [32]


а что, уже пули свистели ?)


 
andsin   (2005-09-27 15:29) [34]

ё- да тут не только пули... тут уже и раки на горе свистели.
реализовал через приведение к TMethod. не нравится. :( а куда деваться?
всем спасибо за помощь. :)


 
Digitman ©   (2005-09-27 15:35) [35]


> andsin   (27.09.05 15:29) [34]


> реализовал через приведение к TMethod


ну я ж тебе сказал в [24] - НИКТО не обязывает тебя заниматься какими-то там "приведениями" ! НЕТ там никаких упоминаний о TMethod, коль скоро уж они тебя напрягают)

чем не устраивает-то такой вариант ?

и ЧТО тебе непонятно в СУТИ работы компилятора, когда он имеет дело с методами объектов, тобой тем или иным образом объявляемых ?


 
andsin   (2005-09-27 15:47) [36]

а, вот ты о чем... так в [24] ты наерундил, мягко говоря.
коротенькая программка тебя в этом убедит.

procedure TForm1.FormCreate(Sender: TObject);
begin
 ShowMessage(IntToStr(sizeof(TNotifyEvent)-sizeof(@Form1.OnClick)));
end;

если нет, пиши. :)
а непонятно то, как сравнивать встроенный тип procedure of object без приведений, которые я ненавижу. т.к. тип procedure of object встроен, то, я считаю, должен быть встроен и TNotifyEvent::operator==, извини за С++ еквивалент.


 
Lamer@fools.ua ©   (2005-09-27 15:59) [37]

>я считаю, должен быть встроен и TNotifyEvent::operator==, извини за С++ еквивалент.

Delphi-программист считает, а Борланд располагает  :o)


 
andsin   (2005-09-27 16:10) [38]


> Lamer@fools.ua ©   (27.09.05 15:59) [37]
>
> Delphi-программист считает, а Борланд располагает  :o)

ага. а на начало топика я этого не знал.


 
Digitman ©   (2005-09-27 16:29) [39]


> andsin   (27.09.05 15:47) [36]


> наерундил, мягко говоря


нет, ну ты точно напрашиваешься на LMD))..

"наерундил", говоришь ?

так.
поехали бомбить тебя)

слушай сюда:

sizeof(@Form1.OnClick);

вот это ЖИРНОЕ @ видишь ? разуй лупетки-то )

это ж - АДРЕС структуры !

а адрес в 32-битном ВАП Win32-процесса  - 32-хбитный же) ...т.е. = 4 )

и с какого перепугу размер структуры TMethod (= 8 байт) вдруг будет равен размеру адреса чего-то там  в 32-битном адресном пространстве (= 4 байта) ?


 
evvcom ©   (2005-09-27 16:41) [40]


> andsin   (27.09.05 15:47) [36]

Ты бы еще размер миллионного массива сравнил бы с адресом его начала! А потом бы Борланду претензии предъявил. :)
LMD АднАзначнА! :-)



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2005.10.16;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.052 c
3-1125926607
AndrewK
2005-09-05 17:23
2005.10.16
Хранение справочников в одной таблице. Предлагаю обсудить идею.


14-1127580199
Иван Шихалев
2005-09-24 20:43
2005.10.16
Дейкстра и Вирт в электронном виде


1-1127326732
френк
2005-09-21 22:18
2005.10.16
GetProcAddress


6-1119465288
bugman
2005-06-22 22:34
2005.10.16
UDP Redirect, port mapping, TidMappedPortUDP


14-1127281640
КаПиБаРа
2005-09-21 09:47
2005.10.16
Я считаю что в школе пора вводить предмет Толерантность





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский