Название: Как сделать плагин с интерфейсами в Qt, для приложения на Delphi
Отправлено: antoshib от Июль 25, 2014, 13:23
Всем привет. Есть приложение с плагинами, сделано на дельфи, нужно для него сделать плагин на Qt. Как это сделано в дельфе: ... type TInitPluginFunc = function(const ACore: IInterface; const Id: word): IInterface; safecall; TDonePluginFunc = procedure; safecall; type IPlugin = interface; ICore = interface; IPlugin = interface(IUnknown) ['{99F35F04-99EC-4FF8-908A-0154CC303CFD}'] function PluginDo(This: cardinal): cardinal; safecall; end; ICore = interface(IUnknown) ['{3BAA3534-5422-42B9-BDEA-1CE1037295B3}'] function CoreDo(This: cardinal): cardinal; safecall; end;
Ядро грузит плагин (dll), получает из него функции Init и Done. Вызов Init инициализирует плагин, при этом как аргумент передается интерфейс ядра, возвращает интерфейс плагина: ... var APlugin: IInterface; fPlugin: IPlugin; begin ... //Инициализирует плагин и получает IInterface APlugin:=Init(Core, Id); //Подключает интерфейс плагина к fPlugin: IPlugin Supports(APlugin, IPlugin, fPlugin); ... //какие-то действия с плагином smth2:=fPlugin.PluginDo(smth1); ... //Освобождение ссылки на интерфейс fPlugin:=nil; ...
Пример реализации Init в плагине на делфе: type TPlugin = class(TInterfacedObject, IUnknown, IPlugin) private fCore: ICore; protected function PluginDo(This: cardinal): cardinal; safecall; public constructor Create(const ACore: IInterface; const Id: word); destructor Destroy; override; end; function Init(const ACore: IInterface; const Id: word): IInterface; safecall; begin Result := TPlugin.Create(ACore, Id); end; constructor TPlugin.Create(const ACore: IInterface; const Id: word); begin inherited Create; //Подключение интерфейса ядра if not Supports(ACore, ICore, fCore) then Assert(False); end;
Подскажите ребята, куда копать? Как сделать аналогичный плагин на Qt?
Название: Re: Как сделать плагин с интерфейсами в Qt, для приложения на Delphi
Отправлено: alex312 от Июль 25, 2014, 13:44
копать вам в сторону ActiveQt (http://qt-project.org/doc/qt-5/activeqt-index.html)
Название: Re: Как сделать плагин с интерфейсами в Qt, для п
Отправлено: antoshib от Июль 30, 2014, 08:14
Теперь все переделал, в соответствии с примером OpenGL Example (ActiveQt). Там тоже делают наследование от существующего интерфейса IObjectSafety. Сейчас мой код выглядит следующим образом: plugapi.h //... #import "GAPI.tlb" no_implementation using namespace GAPI; //.... // класс с наследованием от импортированного интерфейса IPluginOutside // class AxPluginOutsideImpl : public QAxAggregated, public IPluginOutside { public: AxPluginOutsideImpl() {}
long queryInterface(const QUuid &iid, void **iface); QAXAGG_IUNKNOWN
BSTR STDMETHODCALLTYPE Get_Name(void); BSTR STDMETHODCALLTYPE Get_Version(void); uint STDMETHODCALLTYPE ExecuteTicket(long Ticket); };
// основной класс, который должен быть виден клиентам // class GQPlugin : public QObject, public QAxBindable { Q_OBJECT Q_CLASSINFO("ClassID", "{3c126a91-a880-4a42-b37c-c9041b1946bc}") Q_CLASSINFO("InterfaceID", "{D8D09E0D-8C9B-4590-B8F1-5C9216767093}") Q_CLASSINFO("EventsID", "{609c58cb-4811-4d45-bf11-a895e2349e83}") public: GQPlugin(QObject *parent = 0);
QAxAggregated *createAggregate(){ return new AxPluginOutsideImpl(); } };
plugapi.cpp //... #import "GAPI.tlb" implementation_only #define QIID_IPluginOutside QUuid(__uuidof(IPluginOutside))
GQPlugin::GQPlugin(QObject *parent): QObject(parent){}
long AxPluginOutsideImpl::queryInterface(const QUuid &iid, void **iface){
*iface = 0; if ( iid == QIID_IPluginOutside ) *iface = (IPluginOutside*) this; else return E_NOINTERFACE;
AddRef(); return S_OK; }
BSTR STDMETHODCALLTYPE AxPluginOutsideImpl::Get_Name(void) { return L"GQPlugin.1.0"; } BSTR STDMETHODCALLTYPE AxPluginOutsideImpl::Get_Version(void) { return L"1.0"; } uint STDMETHODCALLTYPE AxPluginOutsideImpl::ExecuteTicket( long Ticket ){ return 1; }
main.cpp без изменений остался QAXFACTORY_BEGIN("{43f39e41-f171-42d9-884e-7bb029a8bb16}", "{a1eaf125-2906-4ff7-99ba-3c993408520a}") QAXCLASS(GQPlugin) QAXFACTORY_END()
В клиенте пытаюсь вызывать: //... QAxObject axgp; axgp.setControl( "{3c126a91-a880-4a42-b37c-c9041b1946bc}" ); // class ID. qDebug() << axgp.dynamicCall("Get_Name");
Все успешно собралось, но с клиентской стороны не удается вызвать методы Get_Name, Get_Version, ExecuteTicket - ругается на их отсутствие. Может надо указывать const в методах? Но тогда наследование пропадает.. Если кто-то разбирался - просветите, очень нужно.
Название: Re: Как сделать плагин с интерфейсами в Qt, для приложения на Delphi
Отправлено: antoshib от Август 01, 2014, 10:40
Заработало. Надо объявление класса AxPluginOutsideImpl в plugapi.cpp делать.
|