Форум: "Начинающим";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];
ВнизЯдро - дельфи, плагин - си. Указатель на процедуру. Найти похожие ветки
← →
gosha73 (2006-11-21 16:28) [0]Здравствуйте уважаемые.
Сижу вот ломаю голову. Пишу интерфейс ядра на дельфи. Причем пишу таким образом чтобы возможно было использовать интерфейс с других языков, а именно си.
Есть у меня интерфейсная процедура, которая создает пункт меню. В процедуре соответственно указываю следующие параметры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 просто указатель на сишную или любую другую процедуру мне не ясно.
Заранее спасибо за ответы.
← →
clickmaker © (2006-11-21 16:34) [1]
> А каким образом присвоить событию OnClick просто указатель
> на сишную или любую другую процедуру мне не ясно
не положено. OnClick может быть только of object, о чем в хелпе по TNotifyEvent сказано.
А уж в самой OnClick можешь вызывать что угодно
← →
gosha73 (2006-11-21 16:45) [2]
> clickmaker ©
понимаю.
Но не понимаю каким образом должна выглядеть процедура создания пункта меню, которую я указал выше.
Тогда надо каким либо образом указывать для MenuItem.OnClick какую-нибудь одну дефолтовую процедуру обработки для всех пунктов, но как понять какой пункт был нажат и еще сложнее понять где хранить указатели на функции если таких пунктов много. Неужели никак не обойтись без сохранения указателей где либо и поиска их в соответсвии какой пункт был нажат. Что-то это мне кажется не рациональным подходом.
← →
clickmaker © (2006-11-21 16:50) [3]
> как понять какой пункт был нажат и еще сложнее понять где
> хранить указатели на функции если таких пунктов много
TMenuItem.Tag
← →
gosha73 (2006-11-21 16:57) [4]
> clickmaker ©
спасибо, я об этом тоже думал как о запасном выходе или же создатели VCL как раз таким образом хотели решить вопрос межязыковой совместимости. Но неужели по другому никак такой вопрос не решить. Ведь многие с такими сложностями могут столкнуться.
← →
clickmaker © (2006-11-21 17:02) [5]
> Но неужели по другому никак такой вопрос не решить. Ведь
> многие с такими сложностями могут столкнуться
чессгря, никакой сложности не вижу. Итемы у тебя в сервере создаются, логично, что их события должны там же и обрабатываться. Если нужна кроссязычность, то вот COM как раз для этого, а TNotifyEvent под это не заточен
← →
oxffff © (2006-11-21 17:06) [6]
> gosha73 (21.11.06 16:57) [4]
>
> > clickmaker ©
>
> спасибо, я об этом тоже думал как о запасном выходе или
> же создатели VCL как раз таким образом хотели решить вопрос
> межязыковой совместимости. Но неужели по другому никак такой
> вопрос не решить. Ведь многие с такими сложностями могут
> столкнуться.
Конечно можно. С ассемблером у тебя как?
Также как у тебя c stdcall, cdecall?
← →
oxffff © (2006-11-21 17:11) [7]>clickmaker © (21.11.06 17:02) [5]
> вот COM как раз для этого, а TNotifyEvent под это не заточен
Заточить можно. нужно написать на С++ процедуду на ASM, которая транслирует вызов
mov eax,Object
call @Method
В нужный вызов на С++
← →
clickmaker © (2006-11-21 17:15) [8]
> [7] oxffff © (21.11.06 17:11)
можно. Но если уж взялся за COM, почему бы легальными средствами не пользоваться?
← →
oxffff © (2006-11-21 17:17) [9]
> clickmaker © (21.11.06 17:15) [8]
>
> > [7] oxffff © (21.11.06 17:11)
>
> можно. Но если уж взялся за COM, почему бы легальными средствами
> не пользоваться?
А вот это правильно. ;)
← →
gosha73 (2006-11-21 17:19) [10]
> Конечно можно. С ассемблером у тебя как?
> Также как у тебя c stdcall, cdecall?
с асмом не особо хорошо,
с вызовами разобрался.
> Заточить можно. нужно написать на С++ процедуду на ASM,
> которая транслирует вызов
это конечно можно, но хотелось бы как-нибудь без асма разораться, но походу без асма никак.
К примеру если даже я указатель на процедуру получил, то вызывать процедуру по указателю придется через асм наверно, как то так?
procedure TCore.OnMenuItemClick(Sender: TObject);
var ProcAddr: Pointer;
begin
ProcAddr := Ptr(TTntMenuItem(Sender).Tag);
asm
CALL ProcAddr
end;
end;
Как оно все не почеловечески уж :)
← →
clickmaker © (2006-11-21 17:20) [11]Хотя, может быть у него не COM... А интерфейс - это просто как бы интерфейс...
Но все равно, для того "возможно было использовать интерфейс с других языков", напрашивается именно он
← →
oxffff © (2006-11-21 17:25) [12]>Как оно все не почеловечески уж :)
Тогда стоит пересмотреть свой подход к решению. ;)
← →
Наиль © (2006-11-21 17:27) [13]Цитата:
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);
← →
gosha73 (2006-11-21 17:27) [14]не не, у меня не COM интерфейсы, использую интерфейсы между модулями программы, так как очень удобно.
← →
gosha73 (2006-11-21 17:33) [15]
> Наиль ©
А вот это мастер класс, не слов, спасибо.
← →
Наиль © (2006-11-22 17:29) [16]> А вот это мастер класс, не слов, спасибо.
Я лишь дал код от MBo.
В следующий раз буду давать цитаты под ником Цитатник, чтобы не думали, что я такой умный.
← →
alex_*** © (2006-11-22 18:05) [17]
> 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);
не мой ли это пост... ;) Вроде я в то время как раз спрашивал об этом на мастерах. Как давно было.... Вот уж не думал что всплывет.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.042 c