Russian Qt Forum
Ноябрь 22, 2024, 20:14 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как сделать плагин с интерфейсами в Qt, для приложения на Delphi  (Прочитано 5512 раз)
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?
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #1 : Июль 25, 2014, 13:44 »

копать вам в сторону ActiveQt
Записан
antoshib
Гость
« Ответ #2 : Июль 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 в методах? Но тогда наследование пропадает..
Если кто-то разбирался - просветите, очень нужно.
« Последнее редактирование: Июль 30, 2014, 08:49 от antoshib » Записан
antoshib
Гость
« Ответ #3 : Август 01, 2014, 10:40 »

Заработало. Надо объявление класса AxPluginOutsideImpl в plugapi.cpp делать.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.112 секунд. Запросов: 23.