-
rus_999 (21.01.09 13:00) [0]У меня такая проблема, нужно подключить и использовать плагины Download Master'а в своей программе. Мало с этой технологией сталкивался и никак не получается.
Объявления интерфейсовunit DMPluginIntf;
//описание см. в readme.txt
interface
type
{ IDMInterface }
IDMInterface = interface(IUnknown)
['{B412B405-0578-4B99-BB06-368CDA0B2F8C}']
function DoAction(action: WideString; parameters: WideString): WideString; stdcall;//выполнить какие-либо действия в ДМ
end;
{ IDMPlugIn }
IDMPlugIn = interface(IUnknown)
['{959CD0D3-83FD-40F7-A75A-E5C6500B58DF}']
function getID: WideString; stdcall;
//-----info
function GetName: WideString; stdcall;//получаем инфу о плагине
function GetVersion: WideString; stdcall;//получаем инфу о плагине
function GetDescription(language: WideString): WideString; stdcall;//получаем инфу о плагине
function GetEmail: WideString; stdcall;//получаем инфу о плагине
function GetHomepage: WideString; stdcall;//получаем инфу о плагине
function GetCopyright: WideString; stdcall;//получаем инфу о плагине
function GetMinAppVersion: WideString; stdcall;//получаем минимальную версию ДМ-а с которой может работать плагин
//------
procedure PluginInit(_IDmInterface: IDmInterface); stdcall;//инициализация плагина и передача интерфейса для доступа к ДМ
procedure PluginConfigure(params: WideString); stdcall;//вызов окна конфигурации плагина
procedure BeforeUnload; stdcall;
function EventRaised(eventType: WideString; eventData: WideString): WideString; stdcall;//вызывается из ДМ-ма при возникновении какого либо события
{ идентификатор плагина }
property ID: WideString read getID;
end;
implementation
end.
Реализация тестового плагинаinterface
uses DMPluginIntf, Classes, Dialogs;
const
//укажите здесь информацию о своем плагине
myPluginID = '{45145BBE-DCAE-4187-B981-FE9410F6DA5D}';//обязательно укажите свой уникальный номер плагина (используйте Ctrl+Shift+G для генерации)
myPluginName = 'Download Master Test Plug-in';//название плагина на английском языке
myPluginVersion = '0.1.1.1';
myPluginEmail = 'slava@westbyte.com';
myPluginHomePage = 'http://www.westbyte.com/dm/';
myPluginCopyRight = chr(169)+'2006 WestByte';
myMinNeedAppVersion = '5.0.2';//версия указывается без билда
//описание плагина. Должно быть представлено на русском и английском языках. Может содержать подробную инструкцию по пользованию плагином.
myPluginDescription = 'Test Plug-in for show how create plugins for DM';
myPluginDescriptionRussian = 'Тестовый плагин для демонстрации как создавать плагины для DM. Является одновременно шаблоном для создания плагинов. Язык реализации Delphi 7.';
type
TDMTestPlugIn = class(TInterfacedObject, IDMPlugIn)
private
myIDmInterface: IDmInterface;
protected
public
function getID: WideString; stdcall;
//-----info
function GetName: WideString; stdcall;//получаем инфу о плагине
function GetVersion: WideString; stdcall;//получаем инфу о плагине
function GetDescription(language: WideString): WideString; stdcall;//получаем инфу о плагине
function GetEmail: WideString; stdcall;//получаем инфу о плагине
function GetHomepage: WideString; stdcall;//получаем инфу о плагине
function GetCopyright: WideString; stdcall;//получаем инфу о плагине
function GetMinAppVersion: WideString; stdcall;//получаем минимальную версию ДМ-а с которой может работать плагин
//------
procedure PluginInit(_IDmInterface: IDmInterface); stdcall;//инициализация плагина и передача интерфейса для доступа к ДМ
procedure PluginConfigure(params: WideString); stdcall;//вызов окна конфигурации плагина (окно конфигурации реализуется вами самостоятельно)
procedure BeforeUnload; stdcall;//вызывается перед удалением плагина
function EventRaised(eventType: WideString; eventData: WideString): WideString; stdcall;//вызывается из ДМ-ма при возникновении какого либо события
{ идентификатор плагина }
property ID: WideString read getID;
published
end;
implementation
Дальше реализация функций
Помогите плиз, пробовал так, но не выходит!var
handle : thandle;
PlugIn : function : IDMPlugin;
plug : IDMPlugin;
intf : IDMInterface;
label ex;
begin
handle:=loadlibrary(pchar(extractfilepath(paramstr(0))+'Dll\dmtest_plugin.dll'));
PlugIn:=getprocaddress(handle,'RegisterPlugIn');
plug:=plugin;
plug.GetName;
//plugin.PluginInit(intf);
ex:
freelibrary(handle);
end; -
tesseract © (21.01.09 14:35) [1]А что не выходит то ? Нао печатывался где не попадя вот и не выходит. Читай внимательнее : http://www.interface.ru/fset.asp?Url=/borland/decom_1.htm
-
rus_999 (21.01.09 15:00) [2]При вызове функции getname вылетает с ошибкой.
-
rus_999 (21.01.09 15:03) [3]Подправьте код, большого не прощу! Пока во всем этом разберешься.
-
tesseract © (21.01.09 15:18) [4]
> При вызове функции getname вылетает с ошибкой.
Это я вижу поверь это не одна ошибка. Ты зачем plugin function IDMPlugin обозвал? Он TDMTestPlugin должен быть.
И код plug:=plugin.RegisterPlugin где? В статье всё это великолепно расписано, время на чтение не больше 30 минут. -
rus_999 (21.01.09 15:57) [5]Смысл обращаться за помощью, если тебя читать отправляют вместо решения?! Сама длл определенного формата, я его не задаю, там нет функции plugin.RegisterPlugin.
-
tesseract © (21.01.09 16:09) [6]
> Сама длл определенного формата, я его не задаю, там нет
> функции plugin.RegisterPlugin.
В dpr файле она есть, я в примере специально посмотрел. Там всё как описано в данной статье, там твой пример детально на второй странице разжёван.
> Смысл обращаться за помощью, если тебя читать отправляют
> вместо решения?!
Хоть поймёшь что делаешь. Если хочешь полное решение - это уже коммерческое предложение. -
rus_999 (21.01.09 16:12) [7]Спс, попробую все снова.
-
Korney San © (26.02.09 17:59) [8]Усложним задачу.
Я сделал "расширитель" интерфейса - унаследовал
IDMThunkInterface = interface(IDMInterface)
end;
TDMThunkInterface = class(TInterfacedObject, IDMThunkInterface)
function DoAction(action: WideString; parameters: WideString): WideString; stdcall;
constructor Create(_IDMInterface: IDMInterface; Plugins: PPlgInstances; ConfigForm: PThunkSetupForm);
procedure Free; stdcall;
private
thunkIDMInterface: IDMInterface;
AllPlugins: PPlgInstances;
AForm: PThunkSetupForm;
...
end;
с целью подключать к СВОЕМУ плагину ДРУГИЕ плагины DM и фильтровать их "обмен" с DM, а также получить возможность межплагинного обмена данными.
Ввёл несколько нужных типов:
type
TRegisterPlugIn = function: IDMPlugIn; stdcall;
TPlgInstance = Record
Handle: THandle;
PlgRegister: TRegisterPlugIn;
PlgIntf: IDMPlugIn;
PlgID: WideString;
FileName: String;
end;
TPlgInstances = array of TPlgInstance;
PPlgInstances = ^TPlgInstances;
В своём "стандартном" плагине я делаю так:
procedure TDMTestPlugIn.PluginInit(_IDmInterface: IDmInterface);//инициализация плагина и передача интерфейса для доступа к ДМ
begin
myIDmInterface := _IDmInterface;
...
SetLength(Plugins, 0);
...
myThunk:=nil;
myThunk:=TDMThunkInterface.Create(_IDmInterface, Addr(Plugins), Addr(CF));
//
FindPlugins;
end;
FindPlugins заполняет массив именами найденных плагинов, которые подключаются и отключаются так:
function TDMTestPlugIn.ConnPlg(Idx: Integer): Integer;
begin
if (Idx>=Low(Plugins)) and (Idx<=High(Plugins)) then
begin
Result:=cnxOK;
if FileExists(Plugins[Idx].FileName) then
begin
Plugins[Idx].Handle:=LoadLibrary(PChar(Plugins[Idx].FileName));
if Plugins[Idx].Handle = 0 then
Result:=cnxLoadFailed
else
begin
Plugins[Idx].PlgRegister:=nil;
@Plugins[Idx].PlgRegister := GetProcAddress(Plugins[Idx].Handle, 'RegisterPlugIn');
if Assigned(Plugins[Idx].PlgRegister) then
begin
Plugins[Idx].PlgIntf:=Plugins[Idx].PlgRegister();
Plugins[Idx].PlgID:=Plugins[Idx].PlgIntf.ID;
Plugins[Idx].PlgIntf.PluginInit(myThunk); //отдаю СВОЙ интерфейс
end
else
Result:=cnxNoInit;
end;
end
else
Result:=cnxNotFound;
end
else
Result:=-1;
end;
//------------------------------------------------------------------------------
procedure TDMTestPlugIn.RemPlg(Idx: Integer);
begin
if (Idx>=Low(Plugins)) and (Idx<=High(Plugins)) then
begin
if Plugins[Idx].Handle<>0 then
begin
Plugins[Idx].PlgIntf.BeforeUnload; //"чищу" сам плагин
Plugins[Idx].PlgID:='';
Plugins[Idx].PlgIntf:=nil; //закрываю его интерфейс
Plugins[Idx].PlgRegister:=nil; //очищаю указатель на фукнцию регистрации
FreeLibrary(Plugins[Idx].Handle);
Plugins[Idx].Handle:=0;
end;
end;
end;
Передача данных между подключёнными "в массив" плагинами реализована так:
плагин-отправитель вызывает DoAction у myThunk, а myThunk определяет адресата и вызывает ему EventRaised.
Написал два тестовых плагина - один вызывает команду другого. Отлично работают друг с другом... до той поры, пока один из них не выгрузить (сделал такую возможность) и не загрузить обратно (через RemPlg и ConnPlg соответственно).
После этой операции плагины сами по себе работают, но друг друга "не видят".
Уже сломал голову над поиском причины. Подскажите, пожалуйста, где я свернул не в ту сторону.