Delphi 信息化管理系统开源框架 @ 模块加载

一个模块(以*.dll或*.blp的文件格式)要被框架所加载

可依据以下规范

创建一个单元文件 XXXXModule.pas,比如 StarModuleOneModule.pas

引用 StarOfficeModule.pas,这里定义了一个导出函数 GetStarModuleClass

unit StarOfficeModule;

var
FModuleClass:TStarModuleClass; procedure RegisterStarModuleClass(ModuleClass:TStarModuleClass); begin FModuleClass:=ModuleClass; end; function GetStarModuleClass:TStarModuleClass; begin Result:=FModuleClass; end;

Exports
 GetStarModuleClass;

同时XXXXModule.pas定义一个TStarModule子类,并调用RegisterStarModuleClass将该子类赋给FModuleClass

 1 type
 2   TStarOfficeInformationModule=Class(TStarModule,IStarModuleInfo)
 3   private
 4   protected
 5     function GetModuleInfo:TStarModuleInfo;
 6   public
 7     constructor Create; override;
 8     destructor Destroy; override;
 9 
10     procedure Init; override;
11     procedure final; override;
12   end;
13 
14 initialization
15   RegisterStarModuleClass(TStarOfficeInformationModule);
16 
17 finalization

这样,导出函数 GetStarModuleClass 实际就是返回 模块里的 TStarModule子类TStarOfficeInformationModule

 

模块管理类由TStarModuleManager实现

主程序工程文件引用StarOfficeApplication后,初始化代码会创建一个与Forms.Application同名的TStarOfficeApplication对象

1 constructor TStarOfficeApplication.Create;
2 begin
3   FModuleMgr:=TStarModuleManager.Create;
4 end;

TStarModuleManager.Create会将自己添加到实例工厂(工厂管理下期介绍)

因此可以通过统一接口调用方式获取到模块加载的接口IStarModuleLoader

 1 procedure TStarModuleManager.LoadModuleFromFile(const ModuleFile: string);
 2 var Module:TStarModuleObject;
 3 begin
 4   try
 5     Module:=TStarModuleObject.Create(ModuleFile,self.FLoadBatch);  6     if Module.IsValidModule then
 7       FModuleList.Add(Module)
 8     else Module.Free;
 9   Except
10     on E: Exception do
11     begin
12 
13     end;
14   end;
15 end;

 当调用加载模块文件函数LoadModuleFromFile时,会根据文件名创建一个模块对象TStarModuleObject

 1 constructor TStarModuleObject.Create(const mFile: String;LoadBatch:String='';
2 CreateModuleObjInstance:Boolean=True); 3 var 4 GetModuleClassPro: TGetModuleClassPro; 5 begin 6 FValidModule:=False; 7 FModuleObj := nil; 8 FModuleCls :=nil; 9 FLoadBatch:=LoadBatch; 10 FModuleFileName := mFile; 11 FModuleHandle := self.LoadModule; 12 @GetModuleClassPro := GetProcAddress(FModuleHandle, 'GetStarModuleClass'); 13 if Assigned(GetModuleClassPro) then 14 begin 15 FModuleCls:=GetModuleClassPro; 16 FValidModule:=FModuleCls<>nil; 17 if (FModuleCls<>nil) and (CreateModuleObjInstance) then 18 FModuleObj:=FModuleCls.Create; 19 end; 20 end; 21 22 function TStarModuleObject.LoadModule: THandle; 23 begin 24 Result:=0; 25 case GetModuleType of 26 mtBPL:Result:=SysUtils.LoadPackage(self.FModuleFileName); 27 mtDLL:Result:=Windows.LoadLibrary(Pchar(self.FModuleFileName)); 28 end; 29 end;

从这里可以看出加载过程先是根据文件类型调用加载函数

然后获取模块里的导出函数 GetStarModuleClass 地址并调用,返回TStarModule的子类

根据是否有导出函数 GetStarModuleClas 判断是否是一个有效模块

 
以上就是模块加载的核心过程

你可能感兴趣的:(Delphi 信息化管理系统开源框架 @ 模块加载)