DLL-Entwicklung (FireDAC)
Nach oben zu Arbeiten mit Verbindungen (FireDAC)
In diesem Thema wird beschrieben, wie FireDAC in den dynamischen Linkbibliotheken verwendet wird.
Inhaltsverzeichnis
Allgemeine Informationen
FireDAC kann in einer DLL wie in einer normalen Anwendung verwendet werden. Entwickler müssen aber zwei spezielle DLL-Entwicklungstechniken berücksichtigen.
Gemeinsame Nutzung von Verbindungen in einer Anwendung und einer DLL
Wenn eine Verbindung von einer Anwendung zu einer DLL übertragen werden muss, sollte die Anwendung nicht das Objekt TFDCustomConnection übertragen, weil dies zu AV-Fehlern und anderen Problemen führen könnte. Das ist kein Problem von FireDAC. Das Problem besteht aufgrund der Delphi-RTL/RTTI-Einschränkungen. Eine Verbindung kann nicht mit anderen Prozessen gemeinsam genutzt werden, weil die gemeinsame Nutzung nur innerhalb desselben Adressraums funktioniert.
Um eine Verbindung zwischen einer Anwendung und einer DLL zu übertragen, muss die Anwendung den Wert der Eigenschaft TFDCustomConnection.CliHandle an die DLL übertragen. Hier muss das Handle der Eigenschaft TFDCustomConnection.SharedCliHandle zugewiesen werden.
Nach der Zuweisung an SharedCliHandle kann die DLL-Verbindung durch Setzen von Connected auf True aktiviert werden. Hierzu muss keine Verbindungsdefinition, einschließlich der DriverID, konfiguriert werden. Die Verbindung kann dann als eine normale Datenbankverbindung verwendet werden. Die Verbindung kann schließlich durch Setzen von Connected auf False geschlossen werden. Die physische Verbindung wird dabei nicht geschlossen, deshalb bleibt die Anwendungsverbindung aktiv.
Die Anwendungsverbindung protokolliert keine Statusänderungen, die durch die DLL durchgeführt werden. Daher muss die DLL den Transaktionsstatus beibehalten, der vor dem Aufruf der DLL vorhanden war. Die Anwendung sollte keine Transaktionen in einer DLL verarbeiten oder die Transaktions-Isolationsstufe und andere Einstellungen in einer DLL ändern. Beachten Sie, dass die DLL auch keine Änderungen nachverfolgt, die von der Anwendung durchgeführt werden.
Auch das Festlegen von SharedCliHandle überträgt keine Optionswerte von einer Anwendung zu einem DLL-Verbindungsobjekt. Die DLL-Verbindungsoptionen können genauso wie die Anwendungsverbindungsoptionen festgelegt werden.
Zum Beispiel: Der DLL-Code:
procedure SomeTask(ACliHandle: Pointer); stdcall;
var
oConn: TFDConnection;
oQuery: TFDQuery;
begin
oConn := TFDConnection.Create(nil);
oQuery := TFDQuery.Create(nil);
try
oConn.SharedCliHandle := ACliHandle;
oConn.Connected := True;
oQuery.Connection := oConn;
oQuery.ExecSQL('delete from aaa');
finally
oQuery.Free;
oConn.Free;
end;
end;
exports
SomeTask;
Und der Anwendungscode:
procedure TForm1.Button1Click(Sender: TObject);
type
TSomeTaskProc = procedure (ACliHandle: Pointer); stdcall;
var
hDll: THandle;
pSomeTask: TSomeTaskProc;
begin
hDll := LoadLibrary(PChar('Project2.dll'));
try
@pSomeTask := GetProcAddress(hDll, PChar('SomeTask'));
FDConnection1.StartTransaction;
try
pSomeTask(FDConnection1.CliHandle);
FDConnection1.Commit;
except
FDConnection1.Rollback;
raise;
end;
finally
FreeLibrary(hDll);
end;
end;
- Behandelt keine DLL-Ladefehler.
- Trifft keine Vorkehrungen zum Entladen der FireDAC-DLL – siehe nächstes Kapitel.
- hält die DLL nicht über einen längeren Zeitraum geladen und behält die DLL-Objekte nicht über einen längeren Zeitraum bei.
Entladen einer FireDAC-DLL
Eine Anwendung kann beim Entladen einer DLL, die FireDAC enthält, hängen bleiben. Das Standardsymptom dafür ist, dass die Anwendung beim FreeLibrary-Aufruf hängen bleibt. Dies ist eine Einschränkung von FireDAC, für die es zwei Workarounds gibt:
- Aktivieren Sie den FireDAC-Hintergrundmodus ("silent mode") in der DLL, sodass keine Wartecursor, Dialogfelder usw. von FireDAC angezeigt werden. Fügen Sie dazu den folgenden Code in Ihre DLL-DPR-Datei ein:
uses
FireDAC.UI.Intf;
begin
FFDGUIxSilentMode := True;
end.
- Beenden Sie den FireDAC-Manager vor dem Entladen einer DLL. Dafür muss die DLL eine Prozedur exportieren, die die Prozedur ADTerminate aufruft. Fügen Sie dazu den folgenden Code in Ihre DLL-DPR-Datei ein:
uses
FireDAC.Stan.Factory;
procedure Shutdown;
begin
FDTerminate;
end;
exports
Shutdown;
Importieren Sie dann die Prozedur Shutdown aus der Anwendung, und rufen Sie sie vor dem Aufruf von FreeLibrary auf:
var
Shutdown: procedure;
....
Shutdown := GetProcAddress(hLib, 'Shutdown');
if Assigned(Shutdown) then
Shutdown();
FreeLibrary(hLib);
Siehe auch
Beispiele
- FireDAC DLL Sharing (Beispiel)