Windows 在Visual Basic 6中访问动态加载的DLL(使用LoadLibrary)

Windows 在Visual Basic 6中访问动态加载的DLL(使用LoadLibrary),windows,dll,vb6,Windows,Dll,Vb6,我需要为DLL创建一个包装器,根据需要加载和卸载它(对于那些对这个问题的背景感兴趣的人,请参阅)。我在Visual Basic 6中进行了此操作,下面的示例中的加载和卸载工作正常: Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA"

我需要为DLL创建一个包装器,根据需要加载和卸载它(对于那些对这个问题的背景感兴趣的人,请参阅)。我在Visual Basic 6中进行了此操作,下面的示例中的加载和卸载工作正常:

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 Sub cmdTestLoadingDLL_Click()

    Dim lb As Long, pa As Long    
    lb = LoadLibrary("D:\projects\other\VB_DLLs\TestDLL\TestDLL.dll")    

    Msgbox "Library address: " + lb

    FreeLibrary lb    

End Sub
我可以看到,当messagebox显示时,DLL被加载到内存中,然后被丢弃。然而,调用该方法自然是不够的——我需要在动态加载的DLL中访问这些方法

我怎样才能做到这一点?我想在类mainClass中调用方法getVersion,它位于TestDLL中,如下所示:

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 Sub cmdTestLoadingDLL_Click()

    Dim lb As Long, pa As Long
    Dim versionString As String

    lb = LoadLibrary("D:\projects\other\VB_DLLs\TestDLL\TestDLL.dll")    

    versionString = "- From DLL: " + mainClass.getVersion
    MsgBox versionString

    FreeLibrary lb    

End Sub
但是,

versionString = "- From DLL: " + mainClass.getVersion

抛出一个错误“Object required”。

首先,因为您是通过LoadLibrary调用它的,所以这里没有类-只有函数导出供公共使用。所以你的mainClass参考永远不会起作用。假设您有一个导出的函数getVersion

我会尝试以下方法:

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 Sub Foo
  On Error Resume Next

  Dim lb As Long, pa As Long
  Dim versionString As String
  Dim retValue as Long

  lb = LoadLibrary("D:\projects\other\VB_DLLs\TestDLL\TestDLL.dll")  

  'retrieve the address of getVersion'
  pa = GetProcAddress(lb, "getVersion")

  'Call the getVersion function'
  retValue = CallWindowProc (pa, Me.hWnd, "I want my version", ByVal 0&, ByVal 0&)

  'release the library'
  FreeLibrary lb
End Sub

您需要在此DLL上调用COM方法吗?如果是这样,我一点也不确定这是否可能

  • 马修·科兰德的优秀作品是我首先要看的。有一些强大的引擎盖下COM的东西在那里,绕过正常的VB6技术

  • 还有,它允许您在不使用COM的情况下调用COM方法。我自己从未使用过它,但人们在VB6新闻组上谈论它


基于您的另一个问题-为什么不创建一个将DLL保存在进程之外的包装器?制作一个封装DLL的ActiveX exe。也许你可以设计一个方案,让ActiveX exe定期终止,Windows回收DLL分配的内存——也许有几个层可以做到这一点。这是我创建包装器的部分尝试。:)我想到的策略是创建一个DLL,其中包含加载和卸载攻击性DLL的函数,或者通过包装器DLL访问DLL。使用ActiveX exe而不是ActiveX DLL是否有好处?当我尝试获取函数getVersion的地址时,它总是0(=未找到)。使用DependencyWalker访问DLL时,我也看不到函数。原因可能是什么?我只能看到4个标准函数:DllCanLoadNow、DllGetClassObject、DllRegisterServer和DllLunRegisterServer。这被认为是正确的答案,尽管它不适合我,因为这似乎是正确的方法。我会搜索CallWindowProc。我一直使用这种方法来调用不需要返回任何内容的函数。因此,您可能需要弄清楚CallWindowProc实际上是如何从getVersion函数返回值的。多亏了指向DirectCom的指针,我才能够使用从DirectCom的DLL中收集的想法解决最初的问题。