00001 {*********************************************************}
00002 { }
00003 { Zeos Database Objects }
00004 { Utility Classes for Native Libraries }
00005 { }
00006 { Originally written by Sergey Seroukhov }
00007 { }
00008 {*********************************************************}
00009
00010 {@********************************************************}
00011 { Copyright (c) 1999-2006 Zeos Development Group }
00012 { }
00013 { License Agreement: }
00014 { }
00015 { This library is distributed in the hope that it will be }
00016 { useful, but WITHOUT ANY WARRANTY; without even the }
00017 { implied warranty of MERCHANTABILITY or FITNESS FOR }
00018 { A PARTICULAR PURPOSE. See the GNU Lesser General }
00019 { Public License for more details. }
00020 { }
00021 { The source code of the ZEOS Libraries and packages are }
00022 { distributed under the Library GNU General Public }
00023 { License (see the file COPYING / COPYING.ZEOS) }
00024 { with the following modification: }
00025 { As a special exception, the copyright holders of this }
00026 { library give you permission to link this library with }
00027 { independent modules to produce an executable, }
00028 { regardless of the license terms of these independent }
00029 { modules, and to copy and distribute the resulting }
00030 { executable under terms of your choice, provided that }
00031 { you also meet, for each linked independent module, }
00032 { the terms and conditions of the license of that module. }
00033 { An independent module is a module which is not derived }
00034 { from or based on this library. If you modify this }
00035 { library, you may extend this exception to your version }
00036 { of the library, but you are not obligated to do so. }
00037 { If you do not wish to do so, delete this exception }
00038 { statement from your version. }
00039 { }
00040 { }
00041 { The project web site is located on: }
00042 { http:
00043 { http:
00044 { svn:
00045 { }
00046 { http:
00047 { http:
00048 { }
00049 { }
00050 { }
00051 { Zeos Development Group. }
00052 {********************************************************@}
00053
00054 unit ZPlainLoader;
00055
00056 interface
00057
00058 {$I ZPlain.inc}
00059
00060 {$IFNDEF VER130BELOW}
00061 uses Types;
00062 {$ELSE}
00063 uses ZCompatibility;
00064 {$ENDIF}
00065
00066 type
00067 {** Implements a loader for native library. }
00068 TZNativeLibraryLoader = class (TObject)
00069 private
00070 FLocations: TStringDynArray;
00071 FHandle: LongWord;
00072 FLoaded: Boolean;
00073 protected
00074 function LoadNativeLibrary: Boolean; virtual;
00075 procedure FreeNativeLibrary; virtual;
00076 function GetAddress(ProcName: PChar): Pointer;
00077 public
00078 constructor Create(Locations: array of string);
00079 destructor Destroy; override;
00080
00081 function Load: Boolean; virtual;
00082 procedure LoadIfNeeded; virtual;
00083
00084
00085 property Handle: LongWord read FHandle write FHandle;
00086 property Loaded: Boolean read FLoaded write FLoaded;
00087 end;
00088
00089 implementation
00090
00091 uses SysUtils,
00092 {$IFNDEF UNIX}
00093 Windows,
00094 {$ELSE}
00095 {$IFNDEF FPC}
00096 libc,
00097 {$ENDIF}
00098 {$ENDIF}
00099 ZMessages;
00100
00101 { TZNativeLibraryLoader }
00102
00103 {**
00104 Creates this loader class and assignes main properties.
00105 @param Locations locations of native library on windows platform.
00106 }
00107 constructor TZNativeLibraryLoader.Create(Locations: array of string);
00108 var
00109 I: Integer;
00110 begin
00111 SetLength(FLocations, Length(Locations));
00112 for I := 0 to High(Locations) do
00113 FLocations[I] := Locations[I];
00114 FHandle := 0;
00115 FLoaded := False;
00116 end;
00117
00118 {**
00119 Destroys the library and cleanups the memory.
00120 }
00121 destructor TZNativeLibraryLoader.Destroy;
00122 begin
00123 if Loaded then
00124 FreeNativeLibrary;
00125 inherited Destroy;
00126 end;
00127
00128 {**
00129 Loads a library module.
00130 @return <code>True</code> if library was successfully loaded.
00131 }
00132 function TZNativeLibraryLoader.Load: Boolean;
00133 begin
00134 Result := LoadNativeLibrary;
00135 end;
00136
00137 {**
00138 Loads a library if it was not previously loaded.
00139 }
00140 procedure TZNativeLibraryLoader.LoadIfNeeded;
00141 begin
00142 if not Loaded then
00143 Load;
00144 end;
00145
00146 {**
00147 Loads a library module and initializes the handle.
00148 @return <code>True</code> is library was successfully loaded.
00149 }
00150 function TZNativeLibraryLoader.LoadNativeLibrary: Boolean;
00151 var
00152 I: Integer;
00153 Location: string;
00154 TriedLocations: string;
00155 begin
00156 Loaded := False;
00157 Location := '';
00158 TriedLocations := '';
00159 if Handle = 0 then
00160 begin
00161 for I := 0 to High(FLocations) do
00162 begin
00163 Location := FLocations[I];
00164
00165
00166
00167 {$IFDEF UNIX}
00168 {$IFDEF FPC}
00169 Handle := LoadLibrary(PChar(Location));
00170 {$ELSE}
00171 Handle := HMODULE(dlopen(PChar(Location), RTLD_GLOBAL));
00172 {$ENDIF}
00173 {$ELSE}
00174 Handle := LoadLibrary(PChar(Location));
00175 {$ENDIF}
00176
00177 if Handle <> 0 then
00178 begin
00179 Loaded := True;
00180 Break;
00181 end;
00182 if TriedLocations <> '' then
00183 TriedLocations := TriedLocations + ', ';
00184 TriedLocations := TriedLocations + Location;
00185 end;
00186 end;
00187
00188 if not Loaded then
00189 raise Exception.Create(Format(SLibraryNotFound, [TriedLocations]));
00190 Result := True;
00191 end;
00192
00193 {**
00194 Frees a previously loaded library.
00195 }
00196 procedure TZNativeLibraryLoader.FreeNativeLibrary;
00197 begin
00198 if (Handle <> 0) and Loaded then
00199 FreeLibrary(Handle);
00200 Handle := 0;
00201 Loaded := False;
00202 end;
00203
00204 {**
00205 Gets a procedure address from the loaded library by its name.
00206 @param ProcName a name of the procedure.
00207 @return a procedure address.
00208 }
00209 function TZNativeLibraryLoader.GetAddress(ProcName: PChar): Pointer;
00210 begin
00211 Result := GetProcAddress(Handle, ProcName);
00212 end;
00213
00214 end.
00215
00216