![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ядро - дельфи, плагин - си. Указатель на процедуру. [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 можешь вызывать что угодно