zeoslib  UNKNOWN
 All Files
ZPlainLoader.pas
Go to the documentation of this file.
1  {*********************************************************}
2 { }
3 { Zeos Database Objects }
4 { Utility Classes for Native Libraries }
5 { }
6 { Originally written by Sergey Seroukhov }
7 { }
8 {*********************************************************}
9 
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
12 { }
13 { License Agreement: }
14 { }
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. }
20 { }
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. }
39 { }
40 { }
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) }
45 { }
46 { http://www.sourceforge.net/projects/zeoslib. }
47 { }
48 { }
49 { Zeos Development Group. }
50 {********************************************************@}
51 
52 unit ZPlainLoader;
53 
54 interface
55 
56 {$I ZPlain.inc}
57 
58 uses Types, ZCompatibility;
59 
60 type
61  {** Implements a loader for native library. }
62 
63  { TZNativeLibraryLoader }
64 
65  TZNativeLibraryLoader = class (TObject)
66  private
67  FLocations: TStringDynArray;
68  {$IFDEF FPC}
69  FHandle: PtrInt;
70  {$ELSE}
71  FHandle: THandle; //M.A. LongWord;
72  {$ENDIF}
73  FLoaded: Boolean;
74  FCurrentLocation: String;
75  function ZLoadLibrary(Location: String): Boolean;
76  protected
77  procedure FreeNativeLibrary; virtual;
78  public
79  constructor Create(Locations: array of string);
80  destructor Destroy; override;
81 
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;
88 
89  property Loaded: Boolean read FLoaded write FLoaded;
90  {$IFDEF FPC}
91  property Handle: PtrInt read FHandle write FHandle;
92  {$ELSE}
93  property Handle: THandle { M.A. LongWord} read FHandle write FHandle;
94  {$ENDIF}
95  property CurrentLocation: String read FCurrentLocation write FCurrentLocation;
96  function GetAddress(ProcName: PAnsiChar): Pointer;
97  end;
98 
99 implementation
100 
101 uses SysUtils,
102 {$IFNDEF UNIX}
103  Windows,
104 {$ELSE}
105  {$IFNDEF FPC}
106  libc,
107  {$ENDIF}
108 {$ENDIF}
109  ZMessages;
110 
111 { TZNativeLibraryLoader }
112 
113 {**
114  Creates this loader class and assignes main properties.
115  @param Locations locations of native library on windows platform.
116 }
117 constructor TZNativeLibraryLoader.Create(Locations: array of string);
118 var
119  I: Integer;
120 begin
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 := '';
126  FLoaded := False;
127 end;
128 
129 {**
130  Destroys the library and cleanups the memory.
131 }
132 destructor TZNativeLibraryLoader.Destroy;
133 begin
134  if Loaded then
135  FreeNativeLibrary;
136  inherited Destroy;
137 end;
138 
139 procedure TZNativeLibraryLoader.ClearLocations;
140 begin
141  SetLength(FLocations,0);
142 end;
143 
144 procedure TZNativeLibraryLoader.AddLocation(Location: String);
145 var
146  i: integer;
147 begin
148  if Location <> '' then
149  begin
150  SetLength(FLocations, Length(FLocations) + 1);
151  for i := High(FLocations) downto 1 do
152  FLocations[i] := FLocations[i - 1];
153  FLocations[0] := Location;
154  end;
155 end;
156 
157 {**
158  Loads a library module.
159  @return <code>True</code> if library was successfully loaded.
160 }
161 function TZNativeLibraryLoader.Load: Boolean;
162 begin
163  Result := LoadNativeLibrary;
164 end;
165 
166 {**
167  Loads a library if it was not previously loaded.
168 }
169 procedure TZNativeLibraryLoader.LoadIfNeeded;
170 begin
171  if not Loaded then
172  Load;
173 end;
174 
175 function TZNativeLibraryLoader.ZLoadLibrary(Location: String): Boolean;
176 var newpath, temp: String; // AB modif
177 begin
178  if FLoaded then
179  Self.FreeNativeLibrary;
180  temp := ''; //init for FPC
181  FLoaded := False;
182  Result := False;
183  newpath := ExtractFilePath(Location);
184  // AB modif BEGIN
185  try
186  if newpath <> '' then begin
187  temp := GetCurrentDir;
188  SetCurrentDir(newpath);
189  end;
190  // AB modif END
191 
192 {$IFDEF UNIX}
193  {$IFDEF FPC}
194  FHandle := LoadLibrary(PAnsiChar(Location));
195  {$ELSE}
196  FHandle := HMODULE(dlopen(PAnsiChar(Location), RTLD_GLOBAL));
197  {$ENDIF}
198 {$ELSE}
199  FHandle := LoadLibrary(PChar(Location));
200 {$ENDIF}
201 
202  // AB modif BEGIN
203  finally
204  if temp<>'' then
205  SetCurrentDir(temp);
206  end;
207  // AB modif END
208  if (FHandle <> INVALID_HANDLE_VALUE) and (FHandle <> 0) then
209  begin
210  FLoaded := True;
211  FCurrentLocation := Location;
212  Result := True;
213  end;
214 end;
215 {**
216  Loads a library module and initializes the handle.
217  @return <code>True</code> is library was successfully loaded.
218 }
219 function TZNativeLibraryLoader.LoadNativeLibrary: Boolean;
220 var
221  I: Integer;
222  TriedLocations: string;
223 begin
224  TriedLocations := '';
225  for I := 0 to High(FLocations) do
226  begin
227  if ZLoadLibrary(FLocations[I]) then
228  Break
229  else
230  if TriedLocations <> '' then
231  TriedLocations := TriedLocations + ', ' + FLocations[I]
232  else
233  TriedLocations := FLocations[I];
234  end;
235 
236  if not Loaded then
237  if (Length(FLocations) > 0) and FileExists(FLocations[High(FLocations)]) then
238  raise Exception.Create(Format(SLibraryNotCompatible, [TriedLocations]))
239  else
240  raise Exception.Create(Format(SLibraryNotFound, [TriedLocations]));
241  Result := True;
242 end;
243 
244 function TZNativeLibraryLoader.LoadNativeLibraryStrict(Location: String): Boolean;
245 begin
246  If not ZLoadLibrary(Location) then
247  if FileExists(Location) then
248  raise Exception.Create(Format(SLibraryNotCompatible, [Location]))
249  else
250  raise Exception.Create(Format(SLibraryNotFound, [Location]));
251  Result := True;
252 end;
253 
254 {**
255  Frees a previously loaded library.
256 }
257 procedure TZNativeLibraryLoader.FreeNativeLibrary;
258 begin
259  if (FHandle <> INVALID_HANDLE_VALUE) and (FHandle <> 0) and Loaded then
260  FreeLibrary(Handle);
261  FHandle := INVALID_HANDLE_VALUE;
262  FLoaded := False;
263  FCurrentLocation := '';
264 end;
265 
266 {**
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.
270 }
271 function TZNativeLibraryLoader.GetAddress(ProcName: PAnsiChar): Pointer;
272 begin
273  Result := GetProcAddress(Handle, ProcName);
274 end;
275 
276 end.
277 
278 
279