1 {*********************************************************}
3 { Zeos Database Objects }
4 { Utility Classes for Native Libraries }
6 { Originally written by Sergey Seroukhov }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
58 uses Types, ZCompatibility;
61 {** Implements a loader for native library. }
63 { TZNativeLibraryLoader }
65 TZNativeLibraryLoader = class (TObject)
67 FLocations: TStringDynArray;
71 FHandle: THandle; //M.A. LongWord;
74 FCurrentLocation: String;
75 function ZLoadLibrary(Location: String): Boolean;
77 procedure FreeNativeLibrary; virtual;
79 constructor Create(Locations: array of string);
80 destructor Destroy; override;
82 procedure ClearLocations;
83 procedure AddLocation(Location: String);
84 function Load: Boolean; virtual;
85 function LoadNativeLibrary: Boolean; virtual;
86 function LoadNativeLibraryStrict(Location: String): Boolean;
87 procedure LoadIfNeeded; virtual;
89 property Loaded: Boolean read FLoaded write FLoaded;
91 property Handle: PtrInt read FHandle write FHandle;
93 property Handle: THandle { M.A. LongWord} read FHandle write FHandle;
95 property CurrentLocation: String read FCurrentLocation write FCurrentLocation;
96 function GetAddress(ProcName: PAnsiChar): Pointer;
111 { TZNativeLibraryLoader }
114 Creates this loader class and assignes main properties.
115 @param Locations locations of native library on windows platform.
117 constructor TZNativeLibraryLoader.Create(Locations: array of string);
121 SetLength(FLocations, Length(Locations));
122 for I := 0 to High(Locations) do
123 FLocations[I] := Locations[I];
124 FHandle := INVALID_HANDLE_VALUE;
125 FCurrentLocation := '';
130 Destroys the library and cleanups the memory.
132 destructor TZNativeLibraryLoader.Destroy;
139 procedure TZNativeLibraryLoader.ClearLocations;
141 SetLength(FLocations,0);
144 procedure TZNativeLibraryLoader.AddLocation(Location: String);
148 if Location <> '' then
150 SetLength(FLocations, Length(FLocations) + 1);
151 for i := High(FLocations) downto 1 do
152 FLocations[i] := FLocations[i - 1];
153 FLocations[0] := Location;
158 Loads a library module.
159 @return <code>True</code> if library was successfully loaded.
161 function TZNativeLibraryLoader.Load: Boolean;
163 Result := LoadNativeLibrary;
167 Loads a library if it was not previously loaded.
169 procedure TZNativeLibraryLoader.LoadIfNeeded;
175 function TZNativeLibraryLoader.ZLoadLibrary(Location: String): Boolean;
176 var newpath, temp: String; // AB modif
179 Self.FreeNativeLibrary;
180 temp := ''; //init for FPC
183 newpath := ExtractFilePath(Location);
186 if newpath <> '' then begin
187 temp := GetCurrentDir;
188 SetCurrentDir(newpath);
194 FHandle := LoadLibrary(PAnsiChar(Location));
196 FHandle := HMODULE(dlopen(PAnsiChar(Location), RTLD_GLOBAL));
199 FHandle := LoadLibrary(PChar(Location));
208 if (FHandle <> INVALID_HANDLE_VALUE) and (FHandle <> 0) then
211 FCurrentLocation := Location;
216 Loads a library module and initializes the handle.
217 @return <code>True</code> is library was successfully loaded.
219 function TZNativeLibraryLoader.LoadNativeLibrary: Boolean;
222 TriedLocations: string;
224 TriedLocations := '';
225 for I := 0 to High(FLocations) do
227 if ZLoadLibrary(FLocations[I]) then
230 if TriedLocations <> '' then
231 TriedLocations := TriedLocations + ', ' + FLocations[I]
233 TriedLocations := FLocations[I];
237 if (Length(FLocations) > 0) and FileExists(FLocations[High(FLocations)]) then
238 raise Exception.Create(Format(SLibraryNotCompatible, [TriedLocations]))
240 raise Exception.Create(Format(SLibraryNotFound, [TriedLocations]));
244 function TZNativeLibraryLoader.LoadNativeLibraryStrict(Location: String): Boolean;
246 If not ZLoadLibrary(Location) then
247 if FileExists(Location) then
248 raise Exception.Create(Format(SLibraryNotCompatible, [Location]))
250 raise Exception.Create(Format(SLibraryNotFound, [Location]));
255 Frees a previously loaded library.
257 procedure TZNativeLibraryLoader.FreeNativeLibrary;
259 if (FHandle <> INVALID_HANDLE_VALUE) and (FHandle <> 0) and Loaded then
261 FHandle := INVALID_HANDLE_VALUE;
263 FCurrentLocation := '';
267 Gets a procedure address from the loaded library by its name.
268 @param ProcName a name of the procedure.
269 @return a procedure address.
271 function TZNativeLibraryLoader.GetAddress(ProcName: PAnsiChar): Pointer;
273 Result := GetProcAddress(Handle, ProcName);