我在VB6中使用以下语法声明并调用dll函数:
'Declare the function Private Declare Sub MYFUNC Lib "mylib.dll" () 'Call the function MYFUNC
调用该函数会导致错误文件找不到:mylib.dll.当应用程序从vb6 IDE或编译的可执行文件运行时,会发生这种情况.
该DLL位于工作目录中,我已经检查过使用sysinternals中的ProcMon.exe查找它.没有失败的加载,但英特尔Fortran dll没有加载(ProcMon跟踪似乎在此之前停止).
我也尝试在WinDbg.exe中运行该应用程序,奇怪的是,它的工作原理!这条线上没有失败. ProcMon跟踪显示以这种方式运行程序时加载Intel Fortran dll.
该DLL由Fortran Composer XE 2011编译.
有人可以提供任何帮助吗?
加载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,errorCode,errorMessage,Len(errorMessage),0&) If result > 0 Then ErrorText = Left$(errorMessage,result) Else ErrorText = "Unknown error" End If End Function