ネイティブDLLを遅延バインディング(動的P/Invoke) VB.NET版

naohiro19
記事: 256
登録日時: 14年前
住所: 愛知県

ネイティブDLLを遅延バインディング(動的P/Invoke) VB.NET版

投稿記事 by naohiro19 » 10年前

ネイティブDLLを遅延バインディング(動的P/Invoke)にあるクラスを(Code Converter | Provided by Telerik)(VB.NETに変換してみました。

CODE:


Imports System.Runtime.InteropServices
Imports System.ComponentModel

Namespace DynamicPInvoke
    ''' 
    ''' DynamicPInvokerはアンマネージDLLの動的なロードと関数の呼び出しをサポートします。
    ''' 
    Public Class DynamicPInvoker
        Implements IDisposable

#Region "WinAPI宣言部"

        
        Friend Shared Function LoadLibrary( lpFileName As String) As IntPtr
        End Function

        
        Friend Shared Function FreeLibrary(hModule As IntPtr) As Boolean
        End Function

        
        Friend Shared Function GetProcAddress(hModule As IntPtr,  lpProcName As String) As IntPtr
        End Function

#End Region


        Private hModule As IntPtr


#Region "コンストラクタ"

        ''' 
        ''' オブジェクトの新しいインスタンスを初期化します。
        ''' ひとつのインスタンスにつきひとつのDLLを使用することが出来ます。
        ''' 
        ''' ロードするDLLの名前またはファイルパスを指定します。
        Public Sub New(dllname As String)
            hModule = LoadLibrary(dllname)
        End Sub

#End Region


#Region "パブリックメンバー"

        ''' 
        ''' アンマネージDLLへの呼び出しが可能かどうかを示す値を取得します。
        ''' Disposeメソッドの呼出し後や、ライブラリのロードに失敗した場合、このプロパティはFalseを返します。
        ''' 
        Public ReadOnly Property IsAlive() As Boolean
            Get
                Return Not Me.bDisposed AndAlso (hModule  IntPtr.Zero)
            End Get
        End Property

        ''' 
        ''' インスタンスがロードしているライブラリに含まれる関数を呼び出すためのSystem.Delegateを取得します。
        ''' 
        ''' System.Delegateによって呼び出す関数名で定義されたデリゲートの型を指定します。
        ''' 関数のポインタが取得できない場合、このメソッドはnull(VBではNothing)を返します。
        Public Function GetDelegate(delegateType As Type) As System.Delegate
            If IfDisposed(hModule) = IntPtr.Zero Then
                Throw New Win32Exception("ライブラリがロードされていません。")
            End If

            ' 関数ポインタを取得
            Dim funcptr As IntPtr = GetProcAddress(hModule, delegateType.Name)

            ' 取得できなければnullを返す
            If funcptr = IntPtr.Zero Then
                Return Nothing
            End If

            ' 関数ポインタからデリゲートを生成して返す
            Return Marshal.GetDelegateForFunctionPointer(funcptr, delegateType)
        End Function

        ''' 
        ''' インスタンスがロードしているライブラリに含まれる関数を呼び出すためのSystem.Delegateを取得します。
        ''' 
        ''' 呼び出す関数名で宣言されたデリゲートを指定します。
        ''' 関数を呼び出すためのデリゲートを格納する変数を指定します。
        ''' 
        ''' デリゲートが取得できなかった場合はfalseが返されます。
        ''' デリゲートが取得できた場合はhandlerにデリゲートが格納されメソッドはtrueを返します。
        ''' 
        Public Function GetDelegate(Of T As Class)(ByRef handler As T) As Boolean
            Dim dgt As System.Delegate = Me.GetDelegate(GetType(T))
            If dgt Is Nothing Then
                handler = Nothing
                Return False
            End If

            handler = DirectCast(DirectCast(dgt, Object), T)

            Return True
        End Function

#End Region


#Region "IDisposable メンバ"

        ''' Disposeが実行されたかどうか。
        Private bDisposed As Boolean = False

        ''' Disposeメソッドによってすでにリソースが解放されているかどうかを取得します。
        Public ReadOnly Property IsDisposed() As Boolean
            Get
                Return bDisposed
            End Get
        End Property

        ''' オブジェクトが破棄されたかどうかを検証し、破棄されている場合はObjectDisposedExceptionを発生させます。
        ''' retパラメータの型を指定します。
        ''' オブジェクトが破棄されていない場合にメソッドが返す戻り値を指定します。
        ''' retパラメータに指定した値がそのまま返されます。
        Private Function IfDisposed(Of T)(ret As T) As T
            IfDisposed()
            Return ret
        End Function

        ''' オブジェクトが破棄されたかどうかを検証し、破棄されている場合はObjectDisposedExceptionを発生させます。
        Private Sub IfDisposed()
            If IsDisposed Then
                Throw New ObjectDisposedException("すでに破棄されたオブジェクトにアクセスされました。")
            End If
        End Sub

        ''' 
        ''' 使用されているリソースを解放します。
        ''' 
        Public Sub Dispose()
            ' 重複呼び出し回避
            If bDisposed Then
                Return
            End If

            ' モジュールを開放
            If hModule  IntPtr.Zero Then
                FreeLibrary(hModule)
            End If

            bDisposed = True
            ' 重複呼び出し回避のためのフラグ
        End Sub

        Private Sub System_IDisposable_Dispose() Implements System.IDisposable.Dispose
            Me.Dispose()
        End Sub

#End Region
    End Class
End Namespace
これを逆コンパイルしたものが以下になりました。
► スポイラーを表示
最後に編集したユーザー naohiro19 on 2015年7月25日(土) 15:22 [ 編集 1 回目 ]

コメントはまだありません。