Valhalla Legends Forums Archive | Visual Basic Programming | calling functions from loaded libraries

AuthorMessageTime
l2k-Shadow
Is this possible? Let's say I use LoadLibrary() to load a .dll and GetProcAddress to retrieve a pointer to a function in the library, how can I then call the function using VB?
September 13, 2006, 3:38 AM
JoeTheOdd
Why?

Declare Function FunctionName lib "DllName.dll" (Arguments as ArgumentTypes) as ReturnType
September 13, 2006, 3:49 AM
UserLoser
[quote author=l2k-Shadow link=topic=15673.msg157824#msg157824 date=1158118718]
Is this possible? Let's say I use LoadLibrary() to load a .dll and GetProcAddress to retrieve a pointer to a function in the library, how can I then call the function using VB?
[/quote]

There is no easy way.  You would have to do some crazy stuff like in this thread
September 13, 2006, 3:49 AM
UserLoser
[quote author=Joe[x86] link=topic=15673.msg157825#msg157825 date=1158119354]
Why?

Declare Function FunctionName lib "DllName.dll" (Arguments as ArgumentTypes) as ReturnType
[/quote]

Perhaps he wants to call Extrawork or CheckRevision or something similiar in another application.
September 13, 2006, 3:50 AM
l2k-Shadow
Alright I'll check that out, thanks.
September 13, 2006, 4:25 AM
TheMinistered
Allright, in MOST cases you shouldn't need to use LoadLibrary.  Most cases Declare Function or Declare Sub should work well.

The only instances might be passing arguements a different method/weirdly (perhaps the dll was written in asm?) or its a different calltype (like fastcall, that example userloser posted calls a function with fastcall, where first two params are passed via registers) etc
September 14, 2006, 11:05 PM
Myndfyr
Since this is the Visual Basic forum, I'll point out that this is one of the benefits of ugrading to Visual Basic 2005 is that this could be much simpler.

I don't know what the calling convention is for ExtraWork, but for a generalized C function, let's say, from SFmpq.dll:
[code]
__declspec(dllexport) int SFileOpenArchive(char* fileName, HMPQ* mpqHandle);
[/code]

Visual Basic 2005 can do this:
[code]
Private Delegate Function SFileOpenArchiveCallback(ByVal fileName As String, _
  ByRef mpqHandle As IntPtr) As Integer

Public Class MpqApi
  Private Shared s_openArchive As SFileOpenArchiveCallback

  <DllImport("kernel32")>_
  Private Shared Function LoadLibrary(ByVal fileName As String) As IntPtr
  <DllImport("kernel32")>_
  Private Shared Function GetProcAddress(ByVal hMod As IntPtr, ByVal proc As String)

  Public Shared Function OpenArchive(ByVal fileName As String) As IntPtr
    If fileName = Nothing Then Throw New ArgumentNullException()

    If s_openArchive = Nothing Then Initialize()

    Dim result As IntPtr = IntPtr.Zero
    Dim opResult As Integer
    opResult = s_openArchive(fileName, ByRef result)
    If opResult <> 1 Throw New Exception("Error code " & opResult)
    Return result
  End Function

  Public Shared Sub Initialize()
    Dim hMod As IntPtr, proc As IntPtr
    hMod = LoadLibrary("sfmpq.dll")
    If hMod = IntPtr.Zero Then Throw New Win32Exception(Marshal.GetLastWin32Error())
    proc = GetProcAddress(hMod, "SFileOpenArchive")
    If proc = IntPtr.Zero Then Throw New Win32Exception(Marshal.GetLastWin32Error())

    s_openArchive = CType(Marshal.GetDelegateForFunctionPointer(proc, GetType(SFileOpenArchiveCallback)), SFileOpenArchiveCallback)
  End Sub

End Class
[/code]

Still wordy, but using .NET 2.0, you can late-bind to any exported function of any DLL that can be LoadLibrary'd as long as you have a compatible delegate.  In truth, you can likely even use the base Delegate type and DynamicInvoke on it as long as you pass the right number of parameters.

Anyway.... just thought I'd throw that out there.  ;)
September 14, 2006, 11:43 PM

Search