第 3 章 Visual C# .NET への移行 66
4.3 その他の注意事項と追加情報
4.3.7 デリゲート オブジェクトを使用したコールバック処理
アンマネージDLL関数には、アプリケーション内に定義した関数をコールバック する機能を提供するものがあります。
コールバックとは、特定の条件が成立した場合などにアンマネージ DLLから、ア プリケーションの登録された関数が呼び出される動作をさします。
コールバック関数の呼び出しは、マネージ アプリケーションから DLL 関数を通 じて間接的に渡されたアドレスに対して行われます。
Visual Basic .NETおよび、C# .NETで作成されたマネージアプリケーションが、コ ールバック関数を要求するDLL関数を使用する方法を説明します。
.NET Framework上のアプリケーションは、デリゲートオブジェクトを使用して、
アンマネージDLLが提供するコールバック機能を実現します。
次のステップで、コールバック処理を実装します。
・Step1:DLL関数、コールバック関数の定義
関数のドキュメントを参照して、その関数がコールバックを必要とするかどうか を判断します。
そして、DLL関数の定義および、コールバック関数のデリゲート宣言を行います。
・Step2:コールバック関数の作成
マネージ アプリケーション内にコールバック関数を作成します。
・Step3:DLL関数呼び出し
引数として、コールバック関数のポインタ(デリゲートオブジェクト)を渡し、
DLL関数を呼び出します。
デリゲートオブジェクトが解放されるまで、アンマネージDLLは。繰り返しコー ルバック関数を呼び出すことができます。
もし、デリゲートオブジェクトが解放された後に、アンマネージDLLがコールバ ック関数を呼び出した場合、予期しない動作異常が発生します。
関数がコールバックされる可能性がある期間内に、デリゲートオブジェクトがガ ーベジコレクタによって解放される事がないように、処理の記述にはご注意くだ さい。
[Visual Basic]
GPC-4301 標準版DLLのGpibSetSrqEvent関数の使用例を示します。
・Step1:DLL関数、コールバック関数の定義
C言語でのGpibSetSrqEvent関数宣言とコールバック関数の型宣言は次の通りです。
List 4-20 コールバック関数型宣言
#define LPSRQCALLBACK VOID WINAPI
typedef void (WINAPI *PLPSRQCALLBACK)(int nBoardNo, DWORD dwUser);
List 4-21 GpibSetSrqEvent関数宣言
int GpibSetSrqEvent(ULONG ulBoardNo, PLPSRQCALLBACK lpOnSrqProc, DWORD dwUser);
Visual Basic .NETで、次のように宣言します。
PLPSRQCALLBACKというデリゲートを宣言します。
List 4-22 コールバック用デリゲート宣言
Delegate Sub PLPSRQCALLBACK(ByVal nBoardNo As Integer, ByVal dwUser As Integer)
List 4-23 GpibSetSrqEvent関数宣言
Declare Function GpibSetSrqEvent Lib "GPC43042.DLL" (ByVal ulBoardNo As Integer, ByVal lpOnSrqProc As PLPSRQCALLBACK, ByVal dwUser As Integer) As Integer
・Step2:コールバック関数の作成
lpSrqProcというコールバック関数を宣言します。
引数パラメータの数、型を、デリゲートPLPSRQCALLBACKと合わせます。
また、下記の例では、デリゲートPLPSRQCALLBACKのオブジェクト保存先をモ ジュール内に定義しています。
List 4-24 コールバック関数 Module Module1
・ ・
Public osp As PLPSRQCALLBACK ・
・ ・
Sub lpOnSrqProc(ByVal dwBoardNo As Integer, ByVal dwUser As Integer) ・
・ ・ End Sub End Module
・Step3:DLL関数呼び出し
関数lpOnSrqProcをコールバック関数として、PLPSRQCALLBACKデリゲートオブジ ェクトを生成します。
デリゲートオブジェクトを、GpibSetSrqEvent関数の第2パラメータに指定して呼び出 します。
List 4-25 GpibSetSrqEvent関数呼び出し
osp = New PLPSRQCALLBACK(AddressOf lpOnSrqProc) nRet = GpibSetSrqEvent(1, osp, 0x55)
以上でコールバック関数の登録は完了です。
[C#]
GPC-4301 標準版DLLのGpibSetSrqEvent関数の使用例を示します。
・Step1:DLL関数、コールバック関数の定義
C言語でのGpibSetSrqEvent関数宣言とコールバック関数の型宣言は次の通りです。
List 4-26 コールバック関数型宣言
#define LPSRQCALLBACK VOID WINAPI
typedef void (WINAPI *PLPSRQCALLBACK)(int nBoardNo, DWORD dwUser);
List 4-27 GpibSetSrqEvent関数宣言
int GpibSetSrqEvent(ULONG ulBoardNo, PLPSRQCALLBACK lpOnSrqProc, DWORD dwUser);
C#で次のように定義します。
PLPSRQCALLBACKというデリゲートを宣言します。
List 4-28 コールバック用デリゲート宣言
public delegate void PLPSRQCALLBACK(int nBoardNo, uint dwUser);
List 4-29 GpibSetSrqEvent関数宣言 [DllImport("gpc43042.dll")]
public static extern int GpibSetSrqEvent(uint ulBoardNo, PLPSRQCALLBACK lpOnSrqProc, uint dwUser);
・Step2:コールバック関数の作成
lpSrqProcというコールバック関数を宣言します。
引数パラメータの数、型を、デリゲートPLPSRQCALLBACKと合わせます。
List 4-30 コールバック関数
void lpOnSrqProc(int dwBoardNo , uint dwUser) {
・
・Step3:DLL関数呼び出し
デリゲートPLPSRQCALLBACKのオブジェクト保存先を定義します。
コールバック関数の呼び出しが繰り返される期間中に解放されないクラスの変 数などにします。
List 4-31 デリゲートオブジェクト保存先変数定義
IFCGPIB.PLPSRQCALLBACK osp;
関数lpOnSrqProcをコールバック関数として、PLPSRQCALLBACKデリゲートオブジ ェクトを生成します。デリゲートオブジェクトを、GpibSetSrqEvent関数の第2パラメ ータに指定して呼び出します。
List 4-32 GpibSetSrqEvent関数呼び出し
osp = new IFCGPIB.PLPSRQCALLBACK (lpOnSrqProc);
nRet = IFCGPIB.GpibSetSrqEvent(1, osp, 0x55);
以上でコールバック関数の登録は完了です。