Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ядро - дельфи, плагин - си. Указатель на процедуру. [D7, Win2k, WinXP]


gosha73 ©   (2006-11-21 16:28:00) 

Здравствуйте уважаемые.
Сижу вот ломаю голову. Пишу интерфейс ядра на дельфи. Причем пишу таким образом чтобы возможно было использовать интерфейс с других языков, а именно си.
Есть у меня интерфейсная процедура, которая создает пункт меню. В процедуре соответственно указываю следующие параметры
procedure CreateMainMenuItem(Caption: PChar; ItemIndex: Integer; ClickProc: TNotifyEvent);
Всё отлично если эту интерфейсную процедуру использовать из дельфи, так как и библиотека и ядро поймут друг друга. Но проблема появится для тех кто пишет на си, а именно у них нет TNotifyEvent как класса, да и вообще у них нет классов дельфи, что и так понятно.
Вопрос состоит в том, как мне обработчик ClickProc реализовать чтобы в си это не было проблемой. Догадываюсь, что через указатель, к примеру:
procedure InsertMenuItem(Caption: PChar; ItemIndex: Integer; ClickProc: Pointer);
Но получив этот указатель каким образом мне его присвоить к процедуре OnClick?

Вот как сейчас я создаю пункт меню:

procedure TMyCore.InsertMenuItem(Caption: PChar; ItemIndex: Integer; ClickProc: TNotifyEvent);
var MenuItem: TMenuItem;
begin
 if (Menu.Items.Count < ItemIndex) then Exit;
 MenuItem         := TMenuItem.Create(nil);
 MenuItem.OnClick := ClickProc;
......
 Menu.Items.Insert(ItemIndex, MenuItem);
end;

А каким образом присвоить событию OnClick просто указатель на сишную или любую другую процедуру мне не ясно.
Заранее спасибо за ответы.


alex_***   (2006-11-22 18:05:00) [1]


> AlexKost ©   (25.04.03 14:59)
> Имеется
> M: TMethod;
> Подскажите как выполнить находящуюся в M процедуру;
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
> MBo ©   (25.04.03 15:02)
> TObjProc=Procedure of object;
> M.Code:=CPP_Proc;
> M.Data:=nil;
> TProc(M);
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
> AlexKost ©   (25.04.03 15:11)
> А если процедура имеет параметры?
> Тогда как выполнить?
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
> MBo ©   (25.04.03 15:22)
> TObjProc(M)(I,4);

не мой ли это пост... ;) Вроде я в то время как раз спрашивал об этом на мастерах. Как давно было.... Вот уж не думал что всплывет.


Наиль   (2006-11-22 17:29:00) [2]

> А вот это мастер класс, не слов, спасибо.

Я лишь дал код от MBo.
В следующий раз буду давать цитаты под ником Цитатник, чтобы не думали, что я такой умный.


gosha73   (2006-11-21 17:33:00) [3]


> Наиль ©

А вот это мастер класс, не слов, спасибо.


gosha73   (2006-11-21 17:27:00) [4]

не не, у меня не COM интерфейсы, использую интерфейсы между модулями программы, так как очень удобно.


Наиль   (2006-11-21 17:27:00) [5]

Цитата:

AlexKost ©   (25.04.03 14:59)
Имеется
M: TMethod;
Подскажите как выполнить находящуюся в M процедуру;
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
MBo ©   (25.04.03 15:02)
TObjProc=Procedure of object;
M.Code:=CPP_Proc;
M.Data:=nil;
TProc(M);
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
AlexKost ©   (25.04.03 15:11)
А если процедура имеет параметры?
Тогда как выполнить?
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
MBo ©   (25.04.03 15:22)
TObjProc(M)(I,4);

Примичание:

.OnClick:=TNotifyEvent(M);


oxffff   (2006-11-21 17:25:00) [6]

>Как оно все не почеловечески уж :)

Тогда стоит пересмотреть свой подход к решению. ;)


clickmaker   (2006-11-21 17:20:00) [7]

Хотя, может быть у него не COM... А интерфейс - это просто как бы интерфейс...
Но все равно, для того "возможно было использовать интерфейс с других языков", напрашивается именно он


gosha73   (2006-11-21 17:19:00) [8]


> Конечно можно. С ассемблером у тебя как?
> Также как у тебя c stdcall, cdecall?

с асмом не особо хорошо,
с вызовами разобрался.


> Заточить можно. нужно написать на С++ процедуду на ASM,
> которая транслирует вызов

это конечно можно, но хотелось бы как-нибудь без асма разораться, но походу без асма никак.
К примеру если даже я указатель на процедуру получил, то вызывать процедуру по указателю придется через асм наверно, как то так?

procedure TCore.OnMenuItemClick(Sender: TObject);
var ProcAddr: Pointer;
begin
 ProcAddr := Ptr(TTntMenuItem(Sender).Tag);
 asm
   CALL ProcAddr
 end;
end;

Как оно все не почеловечески уж :)


oxffff   (2006-11-21 17:17:00) [9]


> clickmaker ©   (21.11.06 17:15) [8]
>
> > [7] oxffff ©   (21.11.06 17:11)
>
> можно. Но если уж взялся за COM, почему бы легальными средствами
> не пользоваться?


А вот это правильно. ;)


clickmaker   (2006-11-21 17:15:00) [10]


> [7] oxffff ©   (21.11.06 17:11)

можно. Но если уж взялся за COM, почему бы легальными средствами не пользоваться?


oxffff   (2006-11-21 17:11:00) [11]

>clickmaker ©   (21.11.06 17:02) [5]
> вот COM как раз для этого, а TNotifyEvent под это не заточен

Заточить можно. нужно написать на С++ процедуду на ASM, которая транслирует вызов

 mov eax,Object
 call @Method

В нужный вызов на С++


oxffff   (2006-11-21 17:06:00) [12]


> gosha73   (21.11.06 16:57) [4]
>
> > clickmaker ©
>
> спасибо, я об этом тоже думал как о запасном выходе или
> же создатели VCL как раз таким образом хотели решить вопрос
> межязыковой совместимости. Но неужели по другому никак такой
> вопрос не решить. Ведь многие с такими сложностями могут
> столкнуться.


Конечно можно. С ассемблером у тебя как?
Также как у тебя c stdcall, cdecall?


clickmaker   (2006-11-21 17:02:00) [13]


> Но неужели по другому никак такой вопрос не решить. Ведь
> многие с такими сложностями могут столкнуться

чессгря, никакой сложности не вижу. Итемы у тебя в сервере создаются, логично, что их события должны там же и обрабатываться. Если нужна кроссязычность, то вот COM как раз для этого, а TNotifyEvent под это не заточен


gosha73   (2006-11-21 16:57:00) [14]


> clickmaker ©

спасибо, я об этом тоже думал как о запасном выходе или же создатели VCL как раз таким образом хотели решить вопрос межязыковой совместимости. Но неужели по другому никак такой вопрос не решить. Ведь многие с такими сложностями могут столкнуться.


clickmaker   (2006-11-21 16:50:00) [15]


> как понять какой пункт был нажат и еще сложнее понять где
> хранить указатели на функции если таких пунктов много

TMenuItem.Tag


gosha73   (2006-11-21 16:45:00) [16]


> clickmaker ©

понимаю.
Но не понимаю каким образом должна выглядеть процедура создания пункта меню, которую я указал выше.
Тогда надо каким либо образом указывать для MenuItem.OnClick какую-нибудь одну дефолтовую процедуру обработки для всех пунктов, но как понять какой пункт был нажат и еще сложнее понять где хранить указатели на функции если таких пунктов много. Неужели никак не обойтись без сохранения указателей где либо и поиска их в соответсвии какой пункт был нажат. Что-то это мне кажется не рациональным подходом.


clickmaker   (2006-11-21 16:34:00) [17]


> А каким образом присвоить событию OnClick просто указатель
> на сишную или любую другую процедуру мне не ясно

не положено. OnClick может быть только of object, о чем в хелпе по TNotifyEvent сказано.
А уж в самой OnClick можешь вызывать что угодно


Наверх

Титульная страница Поиск, карта сайта Написать письмо