@@ -107,11 +107,13 @@ EDLLImportError = class(Exception)
107
107
108
108
type
109
109
TDynamicDll = class (TComponent)
110
- private
110
+ protected
111
111
function IsAPIVersionStored : Boolean;
112
112
function IsDllNameStored : Boolean;
113
113
function IsRegVersionStored : Boolean;
114
- procedure SetDllName (const Value : String);
114
+ procedure SetDllName (const Value : String); virtual ;
115
+ procedure SetDllPath (const Value : String); virtual ;
116
+ function GetDllFullFileName : String;
115
117
protected
116
118
FDllName : String;
117
119
FDllPath : String;
@@ -127,14 +129,17 @@ TDynamicDll = class(TComponent)
127
129
FOnAfterLoad : TNotifyEvent;
128
130
FOnBeforeUnload : TNotifyEvent;
129
131
130
- function Import (const funcname: AnsiString; canFail : Boolean = True): Pointer;
132
+ procedure CallMapDll ; virtual ;
133
+ function Import (const funcname: String; canFail: Boolean = True): Pointer;
134
+ function Import2 (funcname: String; args: integer=-1 ; canFail: Boolean = True): Pointer;
131
135
procedure Loaded ; override;
132
136
procedure BeforeLoad ; virtual ;
133
137
procedure AfterLoad ; virtual ;
134
138
procedure BeforeUnload ; virtual ;
135
139
function GetQuitMessage : String; virtual ;
136
140
procedure DoOpenDll (const aDllName : String); virtual ;
137
- function GetDllPath : String;
141
+ function GetDllPath : String; virtual ;
142
+ procedure MapDll ; virtual ; abstract ;
138
143
139
144
public
140
145
// Constructors & Destructors
@@ -144,16 +149,19 @@ TDynamicDll = class(TComponent)
144
149
// Public methods
145
150
procedure OpenDll (const aDllName : String);
146
151
function IsHandleValid : Boolean;
147
- procedure LoadDll ;
152
+ function LoadDll : Boolean ;
148
153
procedure UnloadDll ;
149
154
procedure Quit ;
155
+ class function CreateInstance (DllPath: String = ' ' ; DllName: String = ' ' ): TDynamicDll;
156
+ class function CreateInstanceAndLoad (DllPath: String = ' ' ; DllName: String = ' ' ): TDynamicDll;
150
157
151
158
// Public properties
152
159
published
153
160
property AutoLoad : Boolean read FAutoLoad write FAutoLoad default True;
154
161
property AutoUnload : Boolean read FAutoUnload write FAutoUnload default True;
155
162
property DllName : String read FDllName write SetDllName stored IsDllNameStored;
156
- property DllPath : String read FDllPath write FDllPath;
163
+ property DllPath : String read FDllPath write SetDllPath;
164
+ property DllFullFileName : String read GetDllFullFileName;
157
165
property APIVersion : Integer read FAPIVersion write FAPIVersion stored IsAPIVersionStored;
158
166
property RegVersion : String read FRegVersion write FRegVersion stored IsRegVersionStored;
159
167
property FatalAbort : Boolean read FFatalAbort write FFatalAbort default True;
@@ -164,11 +172,8 @@ TDynamicDll = class(TComponent)
164
172
property OnBeforeUnload : TNotifyEvent read FOnBeforeUnload write FOnBeforeUnload;
165
173
end ;
166
174
167
-
168
175
implementation
169
176
170
- uses PythonEngine;
171
-
172
177
(* ******************************************************)
173
178
(* * **)
174
179
(* * class TDynamicDll **)
@@ -179,35 +184,29 @@ procedure TDynamicDll.DoOpenDll(const aDllName : String);
179
184
begin
180
185
if not IsHandleValid then
181
186
begin
182
- FDllName := aDllName;
187
+ if aDllName<>' ' then
188
+ FDllName := aDllName;
189
+ SetDllDirectory(PChar(GetDllPath));
183
190
FDLLHandle := SafeLoadLibrary(
184
191
{ $IFDEF FPC}
185
- PAnsiChar(AnsiString(GetDllPath+ DllName))
192
+ PAnsiChar(AnsiString(DllName))
186
193
{ $ELSE}
187
194
GetDllPath+DllName
188
195
{ $ENDIF}
189
196
);
190
197
end ;
191
198
end ;
192
199
200
+ function TDynamicDll.GetDllFullFileName : String;
201
+ begin
202
+ Result := DllPath + DllName;
203
+ end ;
204
+
193
205
function TDynamicDll.GetDllPath : String;
194
- { $IFDEF MSWINDOWS}
195
- var
196
- AllUserInstall: Boolean;
197
- { $ENDIF}
198
206
begin
199
207
Result := DllPath;
200
-
201
- { $IFDEF MSWINDOWS}
202
- if DLLPath = ' ' then begin
203
- IsPythonVersionRegistered(RegVersion, Result, AllUserInstall);
204
- end ;
205
- { $ENDIF}
206
-
207
208
if Result <> ' ' then
208
- begin
209
209
Result := IncludeTrailingPathDelimiter(Result);
210
- end ;
211
210
end ;
212
211
213
212
procedure TDynamicDll.OpenDll (const aDllName : String);
@@ -250,6 +249,7 @@ constructor TDynamicDll.Create(AOwner: TComponent);
250
249
FFatalAbort := True;
251
250
FAutoLoad := True;
252
251
FUseLastKnownVersion := True;
252
+ FDLLHandle := 0 ;
253
253
end ;
254
254
255
255
destructor TDynamicDll.Destroy;
@@ -259,11 +259,11 @@ destructor TDynamicDll.Destroy;
259
259
inherited ;
260
260
end ;
261
261
262
- function TDynamicDll.Import (const funcname: AnsiString ; canFail : Boolean = True ): Pointer;
262
+ function TDynamicDll.Import (const funcname: String ; canFail: Boolean): Pointer;
263
263
var
264
264
E : EDllImportError;
265
265
begin
266
- Result := GetProcAddress( FDLLHandle, PAnsiChar (funcname) );
266
+ Result := GetProcAddress( FDLLHandle, PChar (funcname) );
267
267
if (Result = nil ) and canFail then begin
268
268
{ $IFDEF MSWINDOWS}
269
269
E := EDllImportError.CreateFmt(' Error %d: could not map symbol "%s"' , [GetLastError, funcname]);
@@ -276,6 +276,17 @@ function TDynamicDll.Import(const funcname: AnsiString; canFail : Boolean = True
276
276
end ;
277
277
end ;
278
278
279
+ function TDynamicDll.Import2 (funcname: String; args: integer; canFail: Boolean): Pointer;
280
+ begin
281
+ { $IFDEF WIN32}
282
+ // using STDCall name decoration
283
+ // copy paste the function names from dependency walker to notepad and search for the function name there.
284
+ if args>=0 then
285
+ funcname := ' _' +funcname+' @' +IntToStr(args);
286
+ { $ENDIF}
287
+ Result := Import (funcname, canFail);
288
+ end ;
289
+
279
290
procedure TDynamicDll.Loaded ;
280
291
begin
281
292
inherited ;
@@ -293,9 +304,10 @@ function TDynamicDll.IsHandleValid : Boolean;
293
304
{ $ENDIF}
294
305
end ;
295
306
296
- procedure TDynamicDll.LoadDll ;
307
+ function TDynamicDll.LoadDll : Boolean ;
297
308
begin
298
309
OpenDll( DllName );
310
+ Result := IsHandleValid;
299
311
end ;
300
312
301
313
procedure TDynamicDll.UnloadDll ;
@@ -317,6 +329,7 @@ procedure TDynamicDll.AfterLoad;
317
329
begin
318
330
if Assigned( FOnAfterLoad ) then
319
331
FOnAfterLoad( Self );
332
+ CallMapDll;
320
333
end ;
321
334
322
335
procedure TDynamicDll.BeforeUnload ;
@@ -367,5 +380,44 @@ procedure TDynamicDll.SetDllName(const Value: String);
367
380
FDllName := Value ;
368
381
end ;
369
382
383
+ procedure TDynamicDll.SetDllPath (const Value : String);
384
+ begin
385
+ FDllPath := Value ;
386
+ end ;
387
+
388
+ procedure TDynamicDll.CallMapDll ;
389
+ begin
390
+ try
391
+ MapDll;
392
+ except
393
+ on E: Exception do begin
394
+ if FatalMsgDlg then
395
+ { $IFDEF MSWINDOWS}
396
+ MessageBox( GetActiveWindow, PChar(E.Message), ' Error' , MB_TASKMODAL or MB_ICONSTOP );
397
+ { $ELSE}
398
+ WriteLn( ErrOutput, E.Message );
399
+ { $ENDIF}
400
+ if FatalAbort then Quit;
401
+ end ;
402
+ end ;
403
+ end ;
404
+
405
+ class function TDynamicDll.CreateInstance (DllPath, DllName: String): TDynamicDll;
406
+ begin
407
+ Result := Create(nil );
408
+ if DllPath<>' ' then
409
+ Result.DllPath := DllPath;
410
+ if DllName<>' ' then
411
+ Result.DllName := DllName;
412
+ end ;
413
+
414
+ class function TDynamicDll.CreateInstanceAndLoad (DllPath, DllName: String): TDynamicDll;
415
+ begin
416
+ Result := CreateInstance(DllPath, DllName);
417
+ Result.LoadDll;
418
+ if not Result.IsHandleValid then
419
+ FreeAndNil(Result);
420
+ end ;
421
+
370
422
end .
371
423
0 commit comments