DLL-Entwicklung (FireDAC)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Arbeiten mit Verbindungen (FireDAC)


In diesem Thema wird beschrieben, wie FireDAC in den dynamischen Linkbibliotheken verwendet wird.

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 der DLL übertragen werden muss, sollte die Anwendung nicht das TFDCustomConnection-Objekt übertragen, weil dies zu Zugriffsverletzungs- und anderen Fehlern führen kann. Dabei handelt es sich nicht um ein FireDAC-Problem. 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. In einer DLL sollten keine Transaktionen behandelt sowie keine Transaktions-Isolationsstufen und andere Einstellungen geändert werden.

Darüber hinaus werden durch Setzen von SharedCliHandle keine Optionswerte von dem Anwendungs- zu einem DLL-Verbindungsobjekt übertragen. 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;

Hinweis: Der Code führt Folgendes nicht aus:

  • Behandeln von DLL-Ladefehlern.
  • Treffen von Vorkehrungen zum Entladen der FireDAC-DLL – siehe nächstes Kapitel.
  • Längeres Beibehalten der geladenen DLL und längeres Beibehalten von DLL-Objekten.

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);

Hinweis: Die obige Vorgehensweise muss für die ActiveX-Server mit integriertem FireDAC verwendet werden.

Siehe auch

Beispiele