DLL の開発(FireDAC)

提供:RAD Studio

接続の操作(FireDAC) への移動


このトピックでは、動的リンク ライブラリでの FireDAC の使用方法を説明します。

概要

FireDAC は、通常のアプリケーションと同様に DLL においても使用することができます。 ただし、開発者は DDL 開発に特化した 2 つのテクニックを把握しておく必要があります。

アプリケーションと DLL 間の接続共有

アプリケーションから DLL に接続を転送する必要がある場合、アプリケーションは TFDCustomConnection オブジェクトを転送してはいけません。これにより、 AV エラーやその他問題が発生する可能性があるからです。 これは、FireDAC の問題ではなく、 Delphi RTL / RTTI の制限によるものです。 共有は同じアドレス空間内でのみ機能するため、接続は別のプロセスとは共有できない点に注意してください。

アプリケーションと DLL 間で接続を転送するには、アプリケーションは TFDCustomConnection.CliHandle プロパテ値を DLL に転送する必要があります。 ここで、ハンドルが TFDCustomConnection.SharedCliHandle プロパティに割り当てられなければなりません。

TFDCustomConnection.SharedCliHandle が割り当てられた後、DLL 接続は、Connected を True に設定することで、アクティブにできます。 接続定義(DriverID を含む)を設定する必要はない点に注意してください。 その後、接続は通常のデータベース接続として使用できます。 最後に、Connected を False に設定すると、閉じることができます。 これは、物理接続を閉じないため、アプリケーションの接続はアクティブのままになります。

アプリケーション接続は、DLL によって実行された状態版かを追跡しません。 このため、DLL は、DLL 呼び出し以前と同じトランザクション状態を保持する必要があります。 アプリケーションは、DLL 内のトランザクションを処理したり、DLL 内のトランザクション分離レベルやその他の設定を変更したりしないように指示されています。 DLL はアプリケーションによって実行された変更も追跡しないことに注意してください。

また、SharedCliHandle を設定しても、オプション値はアプリケーションから DLL 接続オブジェクトに転送されません。 DLL 接続オプションは、アプリケーション接続オプションと同様に設定できます。

たとえば、DLL コードは次のようになります:

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;

そして、アプリケーション コードは次のようになります:

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;


メモ: このコードは次のことを行いません:
  • DLL 読み込みエラーの処理
  • FireDAC DLL アンロードについての注意 - 次の章を参照
  • 読み込み済み DLL の長時間保持や、DLL オブジェクトの長時間保持

FireDAC DLL のアンロード

アプリケーションは、FireDAC を保有する DLL のアンロード時にハングアップする可能性があります。 これの標準的な現象は、FreeLibrary 呼び出し時のアプリケーションのハングアップです。 これは FireDAC の制限によるもので、2 つの回避策があります:

  • DLL で FireDAC のサイレント モードを有効化し、待機カーソルやダイアログなどが FireDAC によって表示されなくなるようにします。 このためには、DLL DPR ファイルに次のように記述します:
uses
  FireDAC.UI.Intf;

begin
  FFDGUIxSilentMode := True;
end.
  • FireDAC マネージャを DLL のアンロードの前に終了させます。 このためには、DLL はプロシージャをエクスポートする必要があります。これは ADTerminate プロシージャを呼び出します。 このためには、DLL DPR ファイルに次のように記述します:
uses
  FireDAC.Stan.Factory;

procedure Shutdown;
begin
  FDTerminate;
end;

exports
  Shutdown;

その後、FreeLibrary を呼び出す前に Shutdown プロシージャをアプリケーションからインポートし呼び出します:

var
  Shutdown: procedure;
....
  Shutdown := GetProcAddress(hLib, 'Shutdown');
  if Assigned(Shutdown) then
    Shutdown();
  FreeLibrary(hLib);
メモ: 上記のテクニックは、FireDAC を内部に持つ ActiveX サーバーに対して、使用する必要があります。

関連項目

サンプル