第 3 章 Visual C# .NET への移行 66
4.2 DLL 関数呼び出し方法
DLLが提供する関数を呼び出すには 次の情報と処理コードの実装が必要です。
・[Step1] DLLおよびそのDLLが提供する関数を識別するための情報
・[Step2] DLL関数を保持するクラスの作成
・[Step3] マネージコードでのプロトタイプ宣言の記述
以上のステップを踏むことでDLL関数の呼び出しが行えます。
DLL 関数の呼び出しは、ほかのマネージ メソッドの場合と同じ方法で、マネー ジ クラスのメソッドを呼び出します。
本章の最後にDLL関数呼び出しの一連のコード例を示します。
・[Step4]DLL関数呼び出し
4.2.1 DLLおよびそのDLLが提供する関数を識別するための情報
DLLの関数を呼び出すためには、関数の名前と、その関数を格納している DLL の 名前を指定する必要があります。
弊社PCI/CompactPCI/CardBus対応Windows用ソフトウェアライブラリGPCシリー ズのDLL名と関数名は、各製品添付のオンラインヘルプにある、関数リファレン ス中のVisual Basic用関数定義か、製品に含まれる既存のVisual Basic用関数定義フ ァイルを参照すれば関数名と、関数をエクスポートしているDLLの名前がわかり ます。
List 4-1 Visual Basic 6.0用の関数宣言例 デジタル入出力ライブラリGPC-2000 Declare Function DioInputPoint Lib "FbiDio.DLL" (ByVal hDeviceHandle As Long, _ ByRef pBuffer As Long, ByVal dwStartNum As Long, ByVal dwNum As Long) As Long
ただし、関数定義に使用されている各引数パラメータの型はVisual Basic .NETでは、
そのまま使用できません。
また、DLL関数が構造体を使用する場合、構造体の定義も各ソフトウェアライブ ラリのオンラインヘルプに記載があります。
識別子の定義は、製品に含まれる既存のVisual Basic用関数定義ファイルを参照し てください。
DLL名 1) 関数名
4.2.2 DLL 関数を保持するクラスを作成します。
C# や Visual Basic を使ってプログラミングしている場合は、DLL 関数をクラス または Visual Basic モジュール内で宣言する必要があります。
DLL関数を呼び出すための専用のクラス作成は必須ではありませんが、DLL 関数
の定義には手間がかかり、エラーの原因にもなりやすいため、クラス を作成して おくと便利です。
クラス内では、呼び出す各 DLL 関数に対して静的メソッドを定義します。
List 4-2 Visual Basic .NETでのクラス例
Imports System.Runtime.InteropServices Public Class IFCDio
Declare Function DioOpen Lib "FbiDio.DLL" (ByVal lpszName As String,_
ByVal fdwAttrs As Integer) As Integer End Class
クラスを作成し、DLL関数定義を静的メソッドとして定義すると、ほかの静的関 数のメソッドを呼び出す場合と同じ方法で、関数を呼び出すことができます。
プラットフォーム呼び出しのためにマネージ クラスを作成するメリットしては 次の事項が挙げられます。
・DLL 関数ごとに別個のクラスを作成することで検索しやすくなる。
・論理的なグループを形成し、オーバーヘッドを減らすことができる。
(一連の関連する DLL 関数に対して 1 つのクラスを作成する。 )
・クラスおよびそのメソッドには、任意の名前を付けることができる。
4.2.3 マネージコードでのプロトタイプ宣言の記述
DLLなどのアンマネージ ライブラリが提供する関数を呼び出すために、.NET
Framework アプリケーションはそのアンマネージ関数を表す、マネージ コード内
の関数プロトタイプを必要とします。
引数パラメータや戻り値の型にご注意ください。対応するマネージ データ型を使
整数データは次の表のように変わりました。
表 4-1 整数データ対応表
Visual Basic 6.0 Visual Basic .NET C# C++ マネージ拡張
16 ビット Integer Short short short
32 ビット Long Integer int int
64 ビット (none) Long Long _int64
また、プラットフォーム呼び出しでは、データを正確にマーシャリングできるよ うにするプロトタイプを作成する必要があります。
構造体や配列を引数パラメータに指定する場合、明示的にデータをマーシャリン グする必要がある場合があります。これについては、後述します。
[Visual Basic]
Declare ステートメントを Function キーワードと Lib キーワードと共に使用し ます。
デジタル入出力ライブラリGPC-2000のオープン、クローズ、接点単位の入力を行 う関数のプロトタイプ宣言例を示します。
GPC-2000の関数は、FbiDio.DLLファイルが提供します。
List 4-3 プロトタイプ宣言例 Visual Basic .NET
Imports System.Runtime.InteropServices
Declare Function DioOpen Lib "FbiDio.DLL" (ByVal lpszName As String,_
ByVal fdwAttrs As Integer) As Integer
Declare Function DioClose Lib "FbiDio.DLL" (ByVal hDeviceHandle As Integer)_
As Integer
Declare Function DioInputPoint Lib "FbiDio.DLL" (ByVal hDeviceHandle As Integer,_
ByRef pBuffer As Integer, ByVal dwStartNum As Integer,_
ByVal dwNum As Integer) As Integer
DllImportAttribute を Shared Function キーワードと共に使用できる場合もありま す。Visual Basic .NET上でDllImportAttributeを使用する方法の詳細は、Microsoft社 のドキュメントをご参照ください。本書では扱いません。
[C#]
DllImportAttribute を使って、DLL と関数を識別します。メソッドに static 修飾子 と extern 修飾子を使ってマークを付けます。
List 4-4 プロトタイプ宣言例 Visual C# .NET using System.Runtime.InteropServices;
[DllImport("fbidio.dll")]
public static extern int DioOpen( string lpszName, uint fdwFlags );
[C++]
DllImportAttribute を使って、DLL と関数を識別します。ラッパー メソッドまた
はラッパー関数には extern "C" でマークを付けます。
List 4-5 プロトタイプ宣言例 Visual C++ .NET using namespace System::Runtime::InteropServices;
[DllImport("fbidio.dll")]
extern "C" HANDLE DioOpen( LPCTSTR lpszName, DWORD fdwFlags );
Visual C++ .NETで ア ン マ ネ ー ジ ア プ リ ケ ー シ ョ ン を 作 成 す る 場 合 は 、 DllImportAttributeを指定するプラットフォーム呼び出しではなく、Visual C++ 6.0 アプリケーションの作成と同じように、ヘッダファイルのインクルード指定と、
インポートライブラリのリンク指定を行うことでDLL関数を呼び出すアプリケー ションを作成することができます。
4.2.4 DLL関数の呼び出し
DLL関数を呼び出す一連のコード例を次に示します。
[Visual Basic]
List 4-6 DLL関数の呼び出し例 Imports System.Runtime.InteropServices
Public Const FBIDIO_FLAG_SHARE As Integer = &H2
Imports System.Runtime.InteropServices Public Class IFCDio
Declare Function DioOpen Lib "FbiDio.DLL" (ByVal lpszName As String,_
ByVal fdwAttrs As Integer) As Integer
Declare Function DioClose Lib "FbiDio.DLL" (ByVal hDeviceHandle As Integer)_
As Integer
Declare Function DioInputPoint Lib "FbiDio.DLL" (ByVal hDeviceHandle As Integer,_
ByRef pBuffer As Integer, ByVal dwStartNum As Integer,_
ByVal dwNum As Integer) As Integer End Class
Public Class DigitalInput Public Shared Sub Main() Dim nRet As Integer
Dim hDeviceHandle As Integer Dim lpszName As String
hDeviceHandle = IFCDio.DioOpen(lpszName, FBIDIO_FLAG_SHARE) If hDeviceHandle = -1 Then
nRet = MessageBox.Show ("Failed to open the device.", _
"DioOpen",MessageBoxButtons.OK,MessageBoxIcon.Error) EndIf
・ ・ ・ End Sub End Class