加载 DLL 时,“找不到文件”通常会产生误导。这可能意味着缺少 DLL 或它所依赖的文件 - 但如果是这种情况,您就会发现 Process Monitor 的问题。
通常,“找不到文件”消息实际上意味着找到了 DLL,但是在加载它或调用该方法时发生了错误。
在 DLL 中调用过程实际上需要三个步骤:
- 找到并加载 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