Accessing dynamically loaded DLL (with LoadLibrary

2019-02-07 11:44发布

问题:

I have a need to create a wrapper for a DLL, loading and unloading it as needed (for those interested in the background of this question, see How to work around memory-leaking 3rd party DLL (no source code) accessed by Tomcat application?) . I'm doing it in Visual Basic 6, and the loading and unloading with the following example works:

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

I can see using Process Explorer that the DLL is loaded to memory when the messagebox is displayed, and is discarded afterwards. However, calling the method is naturally not enough - I need to access the methods within the dynamically loaded DLL.

How can I achieve this? I would like to call the method getVersion in class mainClass, which is in TestDLL, like this:

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

However, the line

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

throws an error "Object required".

回答1:

First of all, since you are calling it via LoadLibrary, there are no classes here - only functions are exported for public consumption. So your mainClass reference would never work. Let's assume you have a function getVersion that is exported.

I would try the following:

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


回答2:

Do you need to call COM methods on this DLL? If so, I'm not at all sure this is possible.

  • Matthew Curland's excellent Advanced Visual Basic 6 is the first place I'd look, though. There's some powerful under-the-hood COM stuff in there that circumvents the normal VB6 techniques.

  • There's also DirectCom, which allows you to call COM methods without using COM. Never used it myself, but people chat about it on the VB6 newsgroup.



标签: windows dll vb6