从 vb6 加载 dll 时找不到文件 [英] File not found when loading dll from vb6

查看:21
本文介绍了从 vb6 加载 dll 时找不到文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 VB6 中使用以下语法声明和调用 dll 函数:

I am declaring and calling a dll function using the following syntax in VB6:

'Declare the function
Private Declare Sub MYFUNC Lib "mylib.dll" ()

'Call the function
MYFUNC

调用函数导致错误File not found: mylib.dll.当应用程序从 vb6 IDE 或已编译的可执行文件运行时,就会发生这种情况.

Calling the function results in the error File not found: mylib.dll. This happens when the application is run from the vb6 IDE or from a compiled executable.

该 dll 位于工作目录中,并且我检查过它是使用 sysinternals 中的 ProcMon.exe 找到的.没有失败的加载,但没有加载 Intel Fortran dll(ProcMon 跟踪似乎在那之前停止了).

The dll is in the working directory, and I have checked that it is found using ProcMon.exe from sysinternals. There are no failed loads, but the Intel Fortran dlls are not loaded (the ProcMon trace seems to stop before then).

我也尝试在 WinDbg.exe 中运行该应用程序,但奇怪的是,它可以工作!这条线上没有失败.ProcMon 跟踪显示以这种方式运行程序时加载了 Intel Fortran dll.

I have also tried running the application in WinDbg.exe, and weirdly, it works! There are no failures on this line. The ProcMon trace shows that the Intel Fortran dlls are loaded when the program is run in this way.

该 dll 使用 Fortran Composer XE 2011 编译.

The dll is compiled with Fortran Composer XE 2011.

谁能提供帮助?

推荐答案

在加载 DLL 时,找不到文件"通常会产生误导.这可能意味着缺少 DLL 或它所依赖的文件 - 但如果是这种情况,您就会发现 Process Monitor 的问题.

When loading DLLs, "file not found" can often be misleading. It may mean that the DLL or a file it depends on is missing - but if that was the case you would have spotted the problem with Process Monitor.

通常,找不到文件"消息实际上意味着找到了DLL,但是在加载它或调用该方法时发生了错误.

Often, the "file not found" message actually means that the DLL was found, but an error occured when loading it or calling the method.

在 DLL 中调用过程实际上分为三个步骤:

There are actually three steps to calling a procedure in a DLL:

  1. 找到并加载 DLL,运行 DllMain 方法(如果存在).
  2. 在 DLL 中找到该过程.
  3. 调用过程.

错误可能发生在任何这些阶段.VB6 在幕后完成所有这些工作,因此您无法判断错误发生在哪里.但是,您可以使用 Windows API 函数控制该过程.这应该告诉您错误发生在哪里.您还可以设置断点并使用 Process Monitor 检查程序在每个点的行为,这可能会为您提供更多见解.

Errors can happen at any of these stages. VB6 does all this behind the scenes so you can't tell where the error is happening. However, you can take control of the process using Windows API functions. This should tell you where the error is happening. You can alse set breakpoints and use Process Monitor to examine your program's behaviour at each point which may give you more insights.

下面的代码显示了如何使用 Windows API 调用 DLL 过程.要运行它,请将代码放入一个新模块中,并将项目的启动对象设置为Sub Main".

The code below shows how you can call a DLL procedure using the Windows API. To run it, put the code into a new module, and set the startup object for your project to "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

这篇关于从 vb6 加载 dll 时找不到文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆