插件管理框架 for Delphi(三)

开发心得 专栏收录该内容
24 篇文章 0 订阅

1       前言

2       插件框架(untDllManager

3       使用举例

3.1   类图

插件类图

3.2   客户端组件

TDll派生出TClientDll

根据真实的动态库接口添加相关属性;

3.2.1    组件定义

unit untClientDll;

 

interface

 

uses

  Windows, Classes, SysUtils, untDllManager, untProcDefine;

 

type

 

  EClientDllError = Class(Exception);

 

  { TClientDll

    o 继承自 TDll;

    o 自动获取 ClientInitialize 地址并保存在 ClientInitialize 属性中;

    o 自动获取 ClientInsertTrigger 地址并保存在 ClientInsertTrigger 属性中;

  }

 

  TClientDll = Class(TDll)

  private

    FClientInitialize: TClientInitialize;

    FClientInsertTrigger: TClientInsertTrigger;

    FClientGetDescription: TClientGetDescription;

    FClientSetup: TClientSetup;

    FDescription: String;

    FUseTrigger: Bool;

  protected

    procedure DoDllLoaded; override;

    procedure DoDllUnLoaded; override;

  public

    constructor Create; override;

    property ClientGetDescription: TClientGetDescription read FClientGetDescription;

    property ClientInitialize: TClientInitialize read FClientInitialize;

    property ClientInsertTrigger: TClientInsertTrigger read FClientInsertTrigger;

    property ClientSetup: TClientSetup read FClientSetup;

    property Description: String read FDescription write FDescription;

    property UseTrigger: Bool read FUseTrigger write FUseTrigger;

  end;

 

implementation

 

{ TClientDll }

 

constructor TClientDll.Create;

begin

  inherited;

  FClientInitialize := nil;

  FClientInsertTrigger := nil;

  FClientGetDescription := nil;

  FClientSetup := nil;

end;

 

procedure TClientDll.DoDllLoaded;

begin

  FClientInitialize := GetProcAddress(csClientInitialize);

  if not Assigned(FClientInitialize) then

    raise EClientDllError.Create('No found of Proc "ClientInitialize".');

  FClientInsertTrigger := GetProcAddress(csClientInsertTrigger);

  if not Assigned(FClientInsertTrigger) then

    raise EClientDllError.Create('No found of Proc "ClientInsertTrigger".');

  //可选接口,即使不存在也不报错。

  FClientGetDescription := GetProcAddress(csClientGetDescription);

  FClientSetup := GetProcAddress(csClientSetup);

  inherited;

end;

 

procedure TClientDll.DoDllUnLoaded;

begin

  inherited;

  FClientInitialize := nil;

  FClientInsertTrigger := nil;

  FClientGetDescription := nil;

  FClientSetup := nil;

end;

 

end.

 

3.2.2    组件使用

procedure TXXXXServer.LoadClientDll(const FileName: String);

//功能:加载一个ClientDll,并将相关数据传递进去

var

  Index: Integer;

  Description: String;

  UseTrigger: Bool;

  AClientDll: TClientDll;

begin

  Index := FClientDlls.Add(FileName);

  if Index < 0 then

    raise EXXXXError.CreateFmt('ClientDll "%s" 之前已经装载.', [FileName]);

  //尝试读取地址

  try

    FClientDlls[Index].Loaded := True;

  finally

    if not FClientDlls[Index].Loaded then

      FClientDlls[Index].Free;

  end;

  //初始化该Client,同时将相关信息传入

  UseTrigger := False;

  AClientDll := TClientDll(FClientDlls[Index]);

  if Assigned(AClientDll.ClientSetup) then

    AClientDll.ClientSetup(mscAppPath + 'Client/', False);

end;

3.3   服务端组件

3.3.1    组件定义

unit untServerDll;

 

interface

 

uses

  Windows, Classes, SysUtils, untDllManager, untProcDefine;

 

type

 

  EServerDllError = Class(Exception);

 

  { TServerDll

    o 继承自 TDll;

    o 自动获取 QueryInterface 地址并保存在QueryInterface属性中;

  }

 

  TServerDll = Class(TDll)

  private

    FFunctions: TObject;

    FQueryInterface: TProcQueryInterface;

  protected

    procedure DoDllLoaded; override;

    procedure DoDllUnLoaded; override;

  public

    procedure RefreshAllFunctionsPermit;

    property Functions: TObject read FFunctions write FFunctions;

    property QueryInterface: TProcQueryInterface read FQueryInterface;

  end;

 

implementation

 

uses

  untFunctionProc;

 

{ TServerDll }

 

procedure TServerDll.DoDllLoaded;

begin

  FQueryInterface := GetProcAddress(csQueryInterface);

  if not Assigned(FQueryInterface) then

    raise EServerDllError.Create('No found of "QueryInterface" Proc.');

  inherited; //此句需要放在后面

end;

 

procedure TServerDll.DoDllUnLoaded;

begin

  inherited;

  FQueryInterface := nil;

end;

 

procedure TServerDll.RefreshAllFunctionsPermit;

var

  I: Integer;

begin

  Assert(FFunctions <> nil);

  for I := 0 to TFunctionList(FFunctions).Count - 1 do

    if TFunction(TFunctionList(FFunctions)[I]).Dll = Self then

      TFunction(TFunctionList(FFunctions)[I]).Permit := Permit;

end;

 

end.

 

3.3.2    组件使用

略。

[文终]

 

 

  • 0
    点赞
  • 12
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值