一個模塊(以*.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 判斷是否是一個有效模塊
以上就是模塊加載的核心過程