DLL をロードするとき、「ファイルが見つかりません」と誤解されることがよくあります。依存している DLL またはファイルが見つからないことを意味している可能性がありますが、その場合は Process Monitor で問題を発見できたはずです。
多くの場合、「ファイルが見つかりません」というメッセージは、実際には DLL が見つかったことを意味しますが、DLL のロード時またはメソッドの呼び出し時にエラーが発生しました。
DLL でプロシージャを呼び出すには、実際には次の 3 つの手順があります。
- DLL を見つけてロードし、存在する場合は DllMain メソッドを実行します。
- DLL でプロシージャを見つけます。
- プロシージャを呼び出します。
エラーは、これらのどの段階でも発生する可能性があります。VB6 はこれらすべてを舞台裏で行うため、エラーがどこで発生しているかはわかりません。ただし、Windows API 関数を使用してプロセスを制御できます。これにより、エラーが発生している場所がわかります。ブレークポイントを設定し、Process Monitor を使用して各ポイントでプログラムの動作を調べることもできます。これにより、より多くの洞察が得られる場合があります。
次のコードは、Windows API を使用して DLL プロシージャを呼び出す方法を示しています。それを実行するには、コードを新しいモジュールに入れ、プロジェクトのスタートアップ オブジェクトを "Sub Main" に設定します。
Option Explicit
' Windows API method declarations
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function CallWindowProc Lib "user32" Alias _
"CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, _
ByVal Msg As Any, ByVal wParam As Any, ByVal lParam As Any) _
As Long
Private Declare Function FormatMessage Lib "kernel32" Alias _
"FormatMessageA" (ByVal dwFlags As Long, lpSource As Long, _
ByVal dwMessageId As Long, ByVal dwLanguageId As Long, _
ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Any) _
As Long
Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Const MyFunc As String = "MYFUNC"
Const MyDll As String = "mylib.dll"
Sub Main()
' Locate and load the DLL. This will run the DllMain method, if present
Dim dllHandle As Long
dllHandle = LoadLibrary(MyDll)
If dllHandle = 0 Then
MsgBox "Error loading DLL" & vbCrLf & ErrorText(Err.LastDllError)
Exit Sub
End If
' Find the procedure you want to call
Dim procAddress As Long
procAddress = GetProcAddress(dllHandle, MyFunc)
If procAddress = 0 Then
MsgBox "Error getting procedure address" & vbCrLf & ErrorText(Err.LastDllError)
Exit Sub
End If
' Finally, call the procedure
CallWindowProc procAddress, 0&, "Dummy message", ByVal 0&, ByVal 0&
End Sub
' Gets the error message for a Windows error code
Private Function ErrorText(errorCode As Long) As String
Dim errorMessage As String
Dim result As Long
errorMessage = Space$(256)
result = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0&, errorCode, 0&, errorMessage, Len(errorMessage), 0&)
If result > 0 Then
ErrorText = Left$(errorMessage, result)
Else
ErrorText = "Unknown error"
End If
End Function