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

查看:532
本文介绍了从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

调用该函数会导致错误找不到文件: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在工作目录中,我已经检查到使用ProcMon来自sysinternals的.exe没有加载失败,但是没有加载英特尔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.

任何人都可以提供任何帮助?

Can anyone offer any help?

推荐答案

加载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函数来控制进程。这应该告诉你发生错误的地方。您可以设置断点,并使用过程监视器来检查程序在每个点的行为,这可能会给您更多见解。

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.

下面的代码显示了如何调用DLL过程使用Windows API。要运行它,将代码放入一个新的模块,并将项目的启动对象设置为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天全站免登陆