|
@@ -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;
|
|
|
|
- TLibEventUnloading = procedure(User: Pointer; Handler: PLibHandler);
|
|
|
|
|
|
+ TLibEventLoading = function(User: Pointer; Handler: PLibHandler): Boolean;
|
|
|
|
+ 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;
|
|
|
|
- Handle : TLibHandle;
|
|
|
|
- Filename : String;
|
|
|
|
- Loading : TLibEventLoading;
|
|
|
|
- Unloading : TLibEventUnloading;
|
|
|
|
- SymCount : Integer;
|
|
|
|
- Symbols : PLibSymbol;
|
|
|
|
- ErrorMsg : String;
|
|
|
|
- RefCount : Integer;
|
|
|
|
|
|
+ InterfaceName: String; { abstract name of the library }
|
|
|
|
+ Defaults : array of String; { list of default library filenames }
|
|
|
|
+ Filename : String; { handle of the current loaded library }
|
|
|
|
+ Handle : TLibHandle; { filename of the current loaded library }
|
|
|
|
+ Loading : TLibEventLoading; { loading event, called after the unit is loaded }
|
|
|
|
+ Unloading : TLibEventUnloading; { unloading event, called before the unit is unloaded }
|
|
|
|
+ SymCount : Integer; { number of symbols }
|
|
|
|
+ Symbols : PLibSymbol; { symbol address- and namelist }
|
|
|
|
+ ErrorMsg : String; { last error message }
|
|
|
|
+ RefCount : Integer; { reference counter }
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
-function LibraryHandler(const AbstractName: String; const Symbols: PLibSymbol; const SymCount: Integer;
|
|
|
|
- const AfterLoading: TLibEventLoading = nil; const BeforeUnloading: TLibEventUnloading = nil): TLibHandler;
|
|
|
|
-function TryInitializeLibrary(var Handler: TLibHandler; const Filenames: array of String;
|
|
|
|
- const User: Pointer = nil; const Weak: Boolean = False): Integer;
|
|
|
|
-function TryInitializeLibrary(var Handler: TLibHandler; const Filename: String;
|
|
|
|
- const User: Pointer = nil; const Weak: Boolean = False): Integer;
|
|
|
|
-function InitializeLibrary(var Handler: TLibHandler; const Filenames: array of String;
|
|
|
|
- const User: Pointer = nil; const Weak: Boolean = False): Integer;
|
|
|
|
-function InitializeLibrary(var Handler: TLibHandler; const Filename: String;
|
|
|
|
- const User: Pointer = nil; const Weak: Boolean = False): Integer;
|
|
|
|
-function ReleaseLibrary(var Handler: TLibHandler; User: Pointer = nil): Integer;
|
|
|
|
|
|
+{ handler definition }
|
|
|
|
+function LibraryHandler(const InterfaceName: String; const DefaultLibraries: array of String;
|
|
|
|
+ const Symbols: PLibSymbol; const SymCount: Integer; const AfterLoading: TLibEventLoading = nil;
|
|
|
|
+ const BeforeUnloading: TLibEventUnloading = nil): TLibHandler;
|
|
|
|
+
|
|
|
|
+{ initialization/finalization }
|
|
|
|
+function TryInitializeLibrary(var Handler: TLibHandler; const LibraryNames: array of String;
|
|
|
|
+ const User: Pointer = nil; const NoSymbolErrors: Boolean = False): Integer;
|
|
|
|
+function TryInitializeLibrary(var Handler: TLibHandler; const LibraryName: String = '';
|
|
|
|
+ const User: Pointer = nil; const NoSymbolErrors: Boolean = False): 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;
|
|
|
|
- const AfterLoading: TLibEventLoading; const BeforeUnloading: TLibEventUnloading): TLibHandler;
|
|
|
|
-begin
|
|
|
|
- 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;
|
|
|
|
|
|
+function LibraryHandler(const InterfaceName: String; const DefaultLibraries: array of String;
|
|
|
|
+ const Symbols: PLibSymbol; const SymCount: Integer; const AfterLoading: TLibEventLoading;
|
|
|
|
+ const BeforeUnloading: TLibEventUnloading): TLibHandler;
|
|
var
|
|
var
|
|
I: Integer;
|
|
I: Integer;
|
|
begin
|
|
begin
|
|
- if Length(Filenames) <= 0 then
|
|
|
|
- begin
|
|
|
|
- Handler.ErrorMsg := SVarInvalid;
|
|
|
|
- Result := -1;
|
|
|
|
- Exit;
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- for I := 0 to High(Filenames) do
|
|
|
|
- begin
|
|
|
|
- Result := TryInitializeLibrary(Handler, Filenames[I], User, Weak);
|
|
|
|
- if Result > 0 then
|
|
|
|
- Exit;
|
|
|
|
- end;
|
|
|
|
|
|
+ Result.InterfaceName := InterfaceName;
|
|
|
|
+ Result.Filename := '';
|
|
|
|
+ Result.Handle := NilHandle;
|
|
|
|
+ Result.Loading := AfterLoading;
|
|
|
|
+ Result.Unloading := BeforeUnloading;
|
|
|
|
+ Result.SymCount := SymCount;
|
|
|
|
+ Result.Symbols := Symbols;
|
|
|
|
+ Result.ErrorMsg := '';
|
|
|
|
+ Result.RefCount := 0;
|
|
|
|
+
|
|
|
|
+ SetLength(Result.Defaults, Length(DefaultLibraries));
|
|
|
|
+ for I := 0 to High(DefaultLibraries) do
|
|
|
|
+ Result.Defaults[I] := DefaultLibraries[I];
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TryInitializeLibrary(var Handler: TLibHandler; const Filename: String;
|
|
|
|
- const User: Pointer; const Weak: Boolean): Integer;
|
|
|
|
|
|
+function TryInitializeLibraryInternal(var Handler: TLibHandler; const LibraryName: String;
|
|
|
|
+ const User: Pointer; const NoSymbolErrors: Boolean): Integer;
|
|
var
|
|
var
|
|
ErrSym: PLibSymbol;
|
|
ErrSym: PLibSymbol;
|
|
begin
|
|
begin
|
|
- Handler.ErrorMsg := '';
|
|
|
|
-
|
|
|
|
- if (Handler.Filename <> '') and (Handler.Filename <> Filename) then
|
|
|
|
|
|
+ if (Handler.Filename <> '') and (Handler.Filename <> LibraryName) 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;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TryInitializeLibrary(var Handler: TLibHandler; const LibraryName: String;
|
|
|
|
+ const User: Pointer; const NoSymbolErrors: Boolean): Integer;
|
|
|
|
+begin
|
|
|
|
+ if LibraryName <> '' then
|
|
|
|
+ begin
|
|
|
|
+ Handler.ErrorMsg := '';
|
|
|
|
+ Result := TryInitializeLibraryInternal(Handler, LibraryName, User, NoSymbolErrors);
|
|
|
|
+ end else
|
|
|
|
+ Result := TryInitializeLibrary(Handler, Handler.Defaults, User, NoSymbolErrors);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TryInitializeLibrary(var Handler: TLibHandler; const LibraryNames: array of String;
|
|
|
|
+ const User: Pointer; const NoSymbolErrors: Boolean): Integer;
|
|
|
|
+var
|
|
|
|
+ I: Integer;
|
|
|
|
+begin
|
|
|
|
+ Handler.ErrorMsg := '';
|
|
|
|
+
|
|
|
|
+ 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 := '';
|
|
Handler.ErrorMsg := '';
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
-function InitializeLibrary(var Handler: TLibHandler; const Filenames: array of String;
|
|
|
|
- const User: Pointer; const Weak: Boolean): Integer;
|
|
|
|
|
|
+function InitializeLibrary(var Handler: TLibHandler; const LibraryNames: array of String;
|
|
|
|
+ const User: Pointer; const NoSymbolErrors: Boolean): Integer;
|
|
begin
|
|
begin
|
|
- Result := TryInitializeLibrary(Handler, Filenames, User, Weak);
|
|
|
|
- RaiseLibraryException(Handler);
|
|
|
|
|
|
+ Result := TryInitializeLibrary(Handler, LibraryNames, User, NoSymbolErrors);
|
|
|
|
+ if Result < 0 then
|
|
|
|
+ RaiseLibraryException(Handler);
|
|
end;
|
|
end;
|
|
|
|
|
|
-function InitializeLibrary(var Handler: TLibHandler; const Filename: String;
|
|
|
|
- const User: Pointer; const Weak: Boolean): Integer;
|
|
|
|
|
|
+function InitializeLibrary(var Handler: TLibHandler; const LibraryName: String;
|
|
|
|
+ const User: Pointer; const NoSymbolErrors: Boolean): Integer;
|
|
begin
|
|
begin
|
|
- Result := TryInitializeLibrary(Handler, Filename, User, Weak);
|
|
|
|
- RaiseLibraryException(Handler);
|
|
|
|
|
|
+ Result := TryInitializeLibrary(Handler, LibraryName, User, NoSymbolErrors);
|
|
|
|
+ if Result < 0 then
|
|
|
|
+ RaiseLibraryException(Handler);
|
|
end;
|
|
end;
|
|
|
|
|
|
-function ReleaseLibrary(var Handler: TLibHandler; User: Pointer): Integer;
|
|
|
|
|
|
+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;
|