| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- (*
- * 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
- /// <summary>
- /// DLL文件管理
- /// </summary>
- 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;
- /// <summary>
- /// 判断指定的Lib文件是否是MyBean的插件文件
- /// </summary>
- function checkIsValidLib(pvUnLoadIfSucc: Boolean = false): Boolean; override;
- /// <summary>
- /// 根据beanID获取插件
- /// </summary>
- function getBean(pvBeanID:string): IInterface; override;
- /// <summary>
- /// 释放Dll句柄
- /// </summary>
- procedure doFreeLibrary;
- /// <summary>
- /// 加载dll文件
- /// </summary>
- function checkLoadLibrary(pvRaiseIfNil: Boolean = true): Boolean;
- /// <summary>
- /// DLL文件
- /// </summary>
- 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.
|