这个DEMO注意是用来看一个DLL所拥有的全部服务接口
演示效果如下
代码如下:
unit Frm_Main; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, QPlugins, QPlugins_base, QPlugins_Params, QPlugins_Loader_Lib; type TForm_Main = class(TForm) edtPluginsFile: TEdit; Label1: TLabel; Button1: TButton; Memo1: TMemo; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); private { Private declarations } procedure EnumFileServices(const AFileName: String); public { Public declarations } end; var Form_Main: TForm_Main; implementation {$R *.dfm} procedure TForm_Main.Button1Click(Sender: TObject); var AExt: String; ALoader: IQLoader; begin // 打开对话框加载DLL if OpenDialog1.Execute then begin // 根据路径的后缀名来判断是加载DLL还是BPL AExt := UpperCase(ExtractFileExt(OpenDialog1.FileName)); if AExt = '.DLL' then begin // 通过路径获取指定的服务接口实例 ALoader := PluginsManager.ByPath('/Loaders/Loader_DLL') as IQLoader; // 创建一个插件加载器 if not Assigned(ALoader) then begin ALoader := TQDLLLoader.Create('', '.dll'); PluginsManager.Loaders.Add(ALoader); end; end else // BPL begin ALoader := PluginsManager.ByPath('/Loaders/Loader_BPL') as IQLoader; if not Assigned(ALoader) then begin ALoader := TQBPLLoader.Create('', '.bpl'); PluginsManager.Loaders.Add(ALoader); end; end; // 加载指定文件名的插件提供的所有服务 ALoader.LoadServices(PWideChar(OpenDialog1.FileName)); // 把路径显示在编辑框中 edtPluginsFile.Text := OpenDialog1.FileName; // 遍历这个文件的服务 EnumFileServices(OpenDialog1.FileName); end; end; // 遍历这个文件拥有的所有服务接口 procedure TForm_Main.EnumFileServices(const AFileName: String); var AInst: HINST; // 遍历服务 procedure EnumServices(AService: IQService); var AList: IQServices; I: Integer; begin // IQServices: 服务列表接口 // IQService: 普通服务接口 // 判断是IQServices还是IQService,如果是IQServices就进去遍历 if Supports(AService, IQServices, AList) then begin for I := 0 to AList.Count - 1 do begin EnumServices(AList.Items[I]); end; end else // 如果是IQService就输出 begin // 获取服务提供者模块句柄 if AService.GetOwnerInstance = AInst then begin // 输出 Memo1.Lines.Add(ServicePath(AService)); end; end; end; begin // GetModuleHandle获取一个模块(dll)的句柄 AInst := GetModuleHandle(PChar(AFileName)); // 输出模块地址 Memo1.Lines.Add(AFileName + ' 注册的服务(基址:' + IntToHex(AInst, 8) + ')'); // 遍历所拥有的服务 EnumServices(PluginsManager as IQService); end; end.