* lib handler: default libraries can be changed now

git-svn-id: trunk@13995 -
This commit is contained in:
ivost 2009-11-01 11:28:17 +00:00
parent 4e35433504
commit a9150ebb8a

View File

@ -58,11 +58,11 @@ Function GetProcAddress(Lib : TlibHandle; ProcName : AnsiString) : Pointer;
mysql.inc of mysql package (advanced) mysql.inc of mysql package (advanced)
} }
Type type
PLibHandler = ^TLibHandler; PLibHandler = ^TLibHandler;
TLibEventLoading = function(User: Pointer; Handler: PLibHandler; out ErrorMsg: String): Boolean; TLibEventLoading = function(User: Pointer; Handler: PLibHandler): Boolean;
TLibEventUnloading = procedure(User: Pointer; Handler: PLibHandler); TLibEventUnloading = procedure(Handler: PLibHandler);
PPLibSymbol = ^PLibSymbol; PPLibSymbol = ^PLibSymbol;
PLibSymbol = ^TLibSymbol; PLibSymbol = ^TLibSymbol;
@ -73,32 +73,41 @@ Type
end; end;
TLibHandler = record TLibHandler = record
AbstractName : String; InterfaceName: String; { abstract name of the library }
Handle : TLibHandle; Defaults : array of String; { list of default library filenames }
Filename : String; Filename : String; { handle of the current loaded library }
Loading : TLibEventLoading; Handle : TLibHandle; { filename of the current loaded library }
Unloading : TLibEventUnloading; Loading : TLibEventLoading; { loading event, called after the unit is loaded }
SymCount : Integer; Unloading : TLibEventUnloading; { unloading event, called before the unit is unloaded }
Symbols : PLibSymbol; SymCount : Integer; { number of symbols }
ErrorMsg : String; Symbols : PLibSymbol; { symbol address- and namelist }
RefCount : Integer; ErrorMsg : String; { last error message }
RefCount : Integer; { reference counter }
end; end;
function LibraryHandler(const AbstractName: String; const Symbols: PLibSymbol; const SymCount: Integer; { handler definition }
const AfterLoading: TLibEventLoading = nil; const BeforeUnloading: TLibEventUnloading = nil): TLibHandler; function LibraryHandler(const InterfaceName: String; const DefaultLibraries: array of String;
function TryInitializeLibrary(var Handler: TLibHandler; const Filenames: array of String; const Symbols: PLibSymbol; const SymCount: Integer; const AfterLoading: TLibEventLoading = nil;
const User: Pointer = nil; const Weak: Boolean = False): Integer; const BeforeUnloading: TLibEventUnloading = nil): TLibHandler;
function TryInitializeLibrary(var Handler: TLibHandler; const Filename: String;
const User: Pointer = nil; const Weak: Boolean = False): Integer; { initialization/finalization }
function InitializeLibrary(var Handler: TLibHandler; const Filenames: array of String; function TryInitializeLibrary(var Handler: TLibHandler; const LibraryNames: array of String;
const User: Pointer = nil; const Weak: Boolean = False): Integer; const User: Pointer = nil; const NoSymbolErrors: Boolean = False): Integer;
function InitializeLibrary(var Handler: TLibHandler; const Filename: String; function TryInitializeLibrary(var Handler: TLibHandler; const LibraryName: String = '';
const User: Pointer = nil; const Weak: Boolean = False): Integer; const User: Pointer = nil; const NoSymbolErrors: Boolean = False): Integer;
function ReleaseLibrary(var Handler: TLibHandler; User: Pointer = nil): Integer; function InitializeLibrary(var Handler: TLibHandler; const LibraryNames: array of String;
const User: Pointer = nil; const NoSymbolErrors: Boolean = False): Integer;
function InitializeLibrary(var Handler: TLibHandler; const LibraryName: String = '';
const User: Pointer = nil; const NoSymbolErrors: Boolean = False): Integer;
function ReleaseLibrary(var Handler: TLibHandler): Integer;
{ errors }
procedure AppendLibraryError(var Handler: TLibHandler; const Msg: String);
function GetLastLibraryError(var Handler: TLibHandler): String; function GetLastLibraryError(var Handler: TLibHandler): String;
procedure RaiseLibraryException(var Handler: TLibHandler); procedure RaiseLibraryException(var Handler: TLibHandler);
{ symbol load/clear }
function LoadLibrarySymbols(const Lib: TLibHandle; const Symbols: PLibSymbol; const Count: Integer; function LoadLibrarySymbols(const Lib: TLibHandle; const Symbols: PLibSymbol; const Count: Integer;
const ErrorSym: PPLibSymbol = nil): Boolean; const ErrorSym: PPLibSymbol = nil): Boolean;
procedure ClearLibrarySymbols(const Symbols: PLibSymbol; const Count: Integer); procedure ClearLibrarySymbols(const Symbols: PLibSymbol; const Count: Integer);
@ -157,50 +166,35 @@ Begin
{$endif} {$endif}
End; End;
function LibraryHandler(const AbstractName: String; const Symbols: PLibSymbol; const SymCount: Integer; function LibraryHandler(const InterfaceName: String; const DefaultLibraries: array of String;
const AfterLoading: TLibEventLoading; const BeforeUnloading: TLibEventUnloading): TLibHandler; const Symbols: PLibSymbol; const SymCount: Integer; const AfterLoading: TLibEventLoading;
begin const BeforeUnloading: TLibEventUnloading): TLibHandler;
Result.AbstractName := AbstractName;
Result.Handle := NilHandle;
Result.Filename := '';
Result.Loading := AfterLoading;
Result.Unloading := BeforeUnloading;
Result.SymCount := SymCount;
Result.Symbols := Symbols;
Result.ErrorMsg := '';
Result.RefCount := 0;
end;
function TryInitializeLibrary(var Handler: TLibHandler; const Filenames: array of String;
const User: Pointer; const Weak: Boolean): Integer;
var var
I: Integer; I: Integer;
begin begin
if Length(Filenames) <= 0 then Result.InterfaceName := InterfaceName;
begin Result.Filename := '';
Handler.ErrorMsg := SVarInvalid; Result.Handle := NilHandle;
Result := -1; Result.Loading := AfterLoading;
Exit; Result.Unloading := BeforeUnloading;
end; Result.SymCount := SymCount;
Result.Symbols := Symbols;
Result.ErrorMsg := '';
Result.RefCount := 0;
for I := 0 to High(Filenames) do SetLength(Result.Defaults, Length(DefaultLibraries));
begin for I := 0 to High(DefaultLibraries) do
Result := TryInitializeLibrary(Handler, Filenames[I], User, Weak); Result.Defaults[I] := DefaultLibraries[I];
if Result > 0 then
Exit;
end;
end; end;
function TryInitializeLibrary(var Handler: TLibHandler; const Filename: String; function TryInitializeLibraryInternal(var Handler: TLibHandler; const LibraryName: String;
const User: Pointer; const Weak: Boolean): Integer; const User: Pointer; const NoSymbolErrors: Boolean): Integer;
var var
ErrSym: PLibSymbol; ErrSym: PLibSymbol;
begin begin
Handler.ErrorMsg := ''; if (Handler.Filename <> '') and (Handler.Filename <> LibraryName) then
if (Handler.Filename <> '') and (Handler.Filename <> Filename) then
begin begin
Handler.ErrorMsg := Format(SLibraryAlreadyLoaded, [Handler.AbstractName, Handler.Filename]); AppendLibraryError(Handler, Format(SLibraryAlreadyLoaded, [Handler.InterfaceName, Handler.Filename]));
Result := -1; Result := -1;
Exit; Exit;
end; end;
@ -208,29 +202,29 @@ begin
Result := InterlockedIncrement(Handler.RefCount); Result := InterlockedIncrement(Handler.RefCount);
if Result = 1 then if Result = 1 then
begin begin
Handler.Handle := LoadLibrary(Filename); Handler.Handle := LoadLibrary(LibraryName);
if Handler.Handle = NilHandle then if Handler.Handle = NilHandle then
begin begin
Handler.ErrorMsg := Format(SLibraryNotLoaded, [Handler.AbstractName, Filename]); AppendLibraryError(Handler, Format(SLibraryNotLoaded, [Handler.InterfaceName, LibraryName]));
Handler.RefCount := 0; Handler.RefCount := 0;
Result := -1; Result := -1;
Exit; Exit;
end; end;
Handler.Filename := Filename; Handler.Filename := LibraryName;
if not LoadLibrarySymbols(Handler.Handle, Handler.Symbols, Handler.SymCount, @ErrSym) and not Weak then if not LoadLibrarySymbols(Handler.Handle, Handler.Symbols, Handler.SymCount, @ErrSym) and not NoSymbolErrors then
begin begin
AppendLibraryError(Handler, Format(SLibraryUnknownSym, [ErrSym^.name, Handler.InterfaceName, LibraryName]));
UnloadLibrary(Handler.Handle); UnloadLibrary(Handler.Handle);
Handler.Handle := NilHandle; Handler.Handle := NilHandle;
Handler.Filename := ''; Handler.Filename := '';
Handler.ErrorMsg := Format(SLibraryUnknownSym, [ErrSym^.name, Handler.AbstractName, Filename]);
Handler.RefCount := 0; Handler.RefCount := 0;
Result := -1; Result := -1;
Exit; Exit;
end; end;
if Assigned(Handler.Loading) and not Handler.Loading(User, @Handler, Handler.ErrorMsg) then if Assigned(Handler.Loading) and not Handler.Loading(User, @Handler) then
begin begin
UnloadLibrary(Handler.Handle); UnloadLibrary(Handler.Handle);
Handler.Handle := NilHandle; Handler.Handle := NilHandle;
@ -238,26 +232,69 @@ begin
Handler.RefCount := 0; Handler.RefCount := 0;
Result := -1; Result := -1;
Exit; Exit;
end else end;
Handler.ErrorMsg := '';
end; end;
end; end;
function InitializeLibrary(var Handler: TLibHandler; const Filenames: array of String; function TryInitializeLibrary(var Handler: TLibHandler; const LibraryName: String;
const User: Pointer; const Weak: Boolean): Integer; const User: Pointer; const NoSymbolErrors: Boolean): Integer;
begin begin
Result := TryInitializeLibrary(Handler, Filenames, User, Weak); if LibraryName <> '' then
RaiseLibraryException(Handler); begin
Handler.ErrorMsg := '';
Result := TryInitializeLibraryInternal(Handler, LibraryName, User, NoSymbolErrors);
end else
Result := TryInitializeLibrary(Handler, Handler.Defaults, User, NoSymbolErrors);
end; end;
function InitializeLibrary(var Handler: TLibHandler; const Filename: String; function TryInitializeLibrary(var Handler: TLibHandler; const LibraryNames: array of String;
const User: Pointer; const Weak: Boolean): Integer; const User: Pointer; const NoSymbolErrors: Boolean): Integer;
var
I: Integer;
begin begin
Result := TryInitializeLibrary(Handler, Filename, User, Weak); Handler.ErrorMsg := '';
RaiseLibraryException(Handler);
if Length(LibraryNames) <= 0 then
begin
if Length(Handler.Defaults) > 0 then
begin
Result := TryInitializeLibrary(Handler, Handler.Defaults, User, NoSymbolErrors);
Exit;
end;
AppendLibraryError(Handler, SVarInvalid);
Result := -1;
Exit;
end;
for I := 0 to High(LibraryNames) do
begin
Result := TryInitializeLibraryInternal(Handler, LibraryNames[I], User, NoSymbolErrors);
if Result > 0 then
begin
Handler.ErrorMsg := '';
Exit;
end;
end;
end; end;
function ReleaseLibrary(var Handler: TLibHandler; User: Pointer): Integer; function InitializeLibrary(var Handler: TLibHandler; const LibraryNames: array of String;
const User: Pointer; const NoSymbolErrors: Boolean): Integer;
begin
Result := TryInitializeLibrary(Handler, LibraryNames, User, NoSymbolErrors);
if Result < 0 then
RaiseLibraryException(Handler);
end;
function InitializeLibrary(var Handler: TLibHandler; const LibraryName: String;
const User: Pointer; const NoSymbolErrors: Boolean): Integer;
begin
Result := TryInitializeLibrary(Handler, LibraryName, User, NoSymbolErrors);
if Result < 0 then
RaiseLibraryException(Handler);
end;
function ReleaseLibrary(var Handler: TLibHandler): Integer;
begin begin
Handler.ErrorMsg := ''; Handler.ErrorMsg := '';
@ -265,7 +302,7 @@ begin
if Result = 0 then if Result = 0 then
begin begin
if Assigned(Handler.Unloading) then if Assigned(Handler.Unloading) then
Handler.Unloading(User, @Handler); Handler.Unloading(@Handler);
ClearLibrarySymbols(Handler.Symbols, Handler.SymCount); ClearLibrarySymbols(Handler.Symbols, Handler.SymCount);
UnloadLibrary(Handler.Handle); UnloadLibrary(Handler.Handle);
Handler.Handle := NilHandle; Handler.Handle := NilHandle;
@ -275,6 +312,14 @@ begin
Handler.RefCount := 0; Handler.RefCount := 0;
end; end;
procedure AppendLibraryError(var Handler: TLibHandler; const Msg: String);
begin
if Handler.ErrorMsg <> '' then
Handler.ErrorMsg := Handler.ErrorMsg + LineEnding + Msg
else
Handler.ErrorMsg := Msg;
end;
function GetLastLibraryError(var Handler: TLibHandler): String; function GetLastLibraryError(var Handler: TLibHandler): String;
begin begin
Result := Handler.ErrorMsg; Result := Handler.ErrorMsg;
@ -287,7 +332,9 @@ var
begin begin
Msg := GetLastLibraryError(Handler); Msg := GetLastLibraryError(Handler);
if Msg <> '' then if Msg <> '' then
raise EInOutError.Create(Msg); raise EInOutError.Create(Msg)
else
raise EInOutError.Create(SUnknown);
end; end;
function LoadLibrarySymbols(const Lib: TLibHandle; const Symbols: PLibSymbol; const Count: Integer; function LoadLibrarySymbols(const Lib: TLibHandle; const Symbols: PLibSymbol; const Count: Integer;