DLL の開発(FireDAC)

提供: RAD Studio
移動先: 案内検索

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


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

概要

FireDAC は、通常のアプリケーションと同様に DLL でも使用することができます。ただし、開発者は DLL 開発に特有の 2 つの手法を頭に入れておく必要があります。

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

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

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

TFDCustomConnection.SharedCliHandle が割り当てられると、Connected を True に設定することで、DLL 接続をアクティブにすることができます。 なお、DriverID を含め、接続定義をセットアップする必要はありません。 これで、この接続を通常のデータベース接続として使用できます。 最後に、Connected を False に設定することで、接続を閉じることができます。 それでも物理的な接続は閉じられないので、アプリケーション接続はアクティブなままです。

アプリケーション接続では、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 とおりの方法があります。

  • 待機カーソルやダイアログなどが FireDAC で表示されないように、DLL で FireDAC のサイレント モードを有効にする。 それには、以下のコードを DLL の DPR ファイルに記述します。
uses
FireDAC.UI.Intf;
begin
FFDGUIxSilentMode := True;
end.
  • DLL のアンロードの前に FireDAC マネージャを終了させる。 それには、ADTerminate 手続きを呼び出す手続きを DLL でエクスポートしなければなりません。 それには、以下のコードを 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 サーバーに使用する必要があります。

関連項目

サンプルは、FireDAC\Samples\Comp Layer\TFDConnection\DLL_Sharing デモを参照。