(*
* Unit owner: D10.天地弦
* blog: http://www.cnblogs.com/dksoft
*
* v0.1.1(2014-11-06 21:27:40)
* 修正checkIsValidLib- bug, 释放时判断是否BPL,bpl按照BPL释放的方式
*
* v0.1.0(2014-08-29 13:00)
* 修改加载方式(beanMananger.dll-改造)
*
* v0.0.1(2014-05-17)
* + first release
*
*
*)
unit mybean.console.loader.dll;
interface
uses
Windows, SysUtils, Classes, mybean.core.intf, superobject, uSOTools,
mybean.console.loader;
type
///
/// DLL文件管理
///
TLibFactoryObject = class(TBaseFactoryObject)
private
FLibHandle:THandle;
FlibFileName: String;
private
procedure doInitalizeBeanFactory;
procedure doCreatePluginFactory;
procedure doInitialize;
procedure SetlibFileName(const Value: String);
public
procedure checkInitialize; override;
procedure cleanup;override;
///
/// 判断指定的Lib文件是否是MyBean的插件文件
///
function checkIsValidLib(pvUnLoadIfSucc: Boolean = false): Boolean; override;
///
/// 根据beanID获取插件
///
function getBean(pvBeanID:string): IInterface; override;
///
/// 释放Dll句柄
///
procedure doFreeLibrary;
///
/// 加载dll文件
///
function checkLoadLibrary(pvRaiseIfNil: Boolean = true): Boolean;
///
/// DLL文件
///
property libFileName: String read FlibFileName write SetlibFileName;
end;
implementation
uses
LoggerImport;
procedure TLibFactoryObject.doCreatePluginFactory;
var
lvFunc:function:IBeanFactory; stdcall;
begin
@lvFunc := GetProcAddress(FLibHandle, PChar('getBeanFactory'));
if (@lvFunc = nil) then
begin
raise Exception.CreateFmt('非法的Plugin模块文件(%s),找不到入口函数(getBeanFactory)', [self.FlibFileName]);
end;
FBeanFactory := lvFunc;
end;
procedure TLibFactoryObject.doFreeLibrary;
begin
FBeanFactory := nil;
if FLibHandle <> 0 then
begin
if LowerCase(ExtractFileExt(FlibFileName)) = '.bpl' then
begin
UnloadPackage(FLibHandle);
end else
begin
FreeLibrary(FLibHandle);
end;
end;
end;
procedure TLibFactoryObject.doInitalizeBeanFactory;
var
lvFunc:procedure(appContext: IApplicationContext; appKeyMap: IKeyMap); stdcall;
begin
@lvFunc := GetProcAddress(FLibHandle, PChar('initializeBeanFactory'));
if (@lvFunc = nil) then
begin
raise Exception.CreateFmt(
'非法的Plugin模块文件(%s),找不到入口函数(initializeBeanFactory)',
[self.FlibFileName]);
end;
lvFunc(appPluginContext, applicationKeyMap);
end;
procedure TLibFactoryObject.doInitialize;
begin
doInitalizeBeanFactory;
doCreatePluginFactory;
FbeanFactory.checkInitalize;
end;
procedure TLibFactoryObject.checkInitialize;
var
lvConfigStr, lvBeanID:AnsiString;
lvBeanConfig:ISuperObject;
i: Integer;
begin
if FbeanFactory = nil then
begin
checkLoadLibrary;
//将配置传入到beanFactory中
for i := 0 to FConfig.A['list'].Length-1 do
begin
lvBeanConfig := FConfig.A['list'].O[i];
lvBeanID := AnsiString(lvBeanConfig.S['id']);
lvConfigStr := AnsiString(lvBeanConfig.AsJSon(false, false));
//配置单个bean
FbeanFactory.configBean(PAnsiChar(lvBeanID), PAnsiChar(lvConfigStr));
end;
end;
//避免提前释放
lvConfigStr := '';
lvBeanID:= '';
end;
function TLibFactoryObject.checkIsValidLib(pvUnLoadIfSucc: Boolean = false): Boolean;
var
lvFunc:procedure(appContext: IApplicationContext; appKeyMap: IKeyMap); stdcall;
lvLibHandle:THandle;
lvIsBpl:Boolean;
begin
Result := False;
if FLibHandle = 0 then
begin
lvIsBpl :=LowerCase(ExtractFileExt(FlibFileName)) = '.bpl';
if lvIsBpl then
begin
lvLibHandle := LoadPackage(FlibFileName);
end else
begin
lvLibHandle := LoadLibrary(PChar(FlibFileName));
end;
if lvLibHandle <> 0 then
begin
try
@lvFunc := GetProcAddress(lvLibHandle, PChar('initializeBeanFactory'));
result := (@lvFunc <> nil);
finally
if Result then
begin
if pvUnLoadIfSucc then
begin
if lvIsBpl then
begin
UnloadPackage(lvLibHandle);
end else
begin
FreeLibrary(lvLibHandle);
end;
end else
begin
FLibHandle := lvLibHandle;
end;
end;
end;
end else
begin
Result := False;
end;
end else
begin // 已经成功加载
Result := true;
end;
end;
function TLibFactoryObject.checkLoadLibrary(pvRaiseIfNil: Boolean = true): Boolean;
begin
if FLibHandle = 0 then
begin
if not FileExists(FlibFileName) then
begin
if pvRaiseIfNil then
begin
raise Exception.Create('文件[' + FlibFileName + ']未找到!');
end;
Result := false;
end else
begin
if LowerCase(ExtractFileExt(FlibFileName)) = '.bpl' then
begin
FLibHandle := LoadPackage(FlibFileName);
end else
begin
FLibHandle := LoadLibrary(PChar(FlibFileName));
end;
end;
end;
Result := FLibHandle <> 0;
if not Result then RaiseLastOSError;
if Result then DoInitialize;
end;
procedure TLibFactoryObject.cleanup;
begin
try
doFreeLibrary;
except
on E: Exception do
Debug(E.Message, 'TLibFactoryObject.cleanup-' + Self.FlibFileName);
end;
end;
function TLibFactoryObject.getBean(pvBeanID:string): IInterface;
begin
result := inherited getBean(pvBeanID);
end;
procedure TLibFactoryObject.SetlibFileName(const Value: String);
begin
FlibFileName := Value;
Fnamespace := FlibFileName;
end;
end.