Valhalla Legends Archive

Programming => General Programming => Visual Basic Programming => Topic started by: l2k-Shadow on September 12, 2006, 10:38 PM

Title: calling functions from loaded libraries
Post by: l2k-Shadow on September 12, 2006, 10:38 PM
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?
Title: Re: calling functions from loaded libraries
Post by: Joe[x86] on September 12, 2006, 10:49 PM
Why?

Declare Function FunctionName lib "DllName.dll" (Arguments as ArgumentTypes) as ReturnType
Title: Re: calling functions from loaded libraries
Post by: UserLoser on September 12, 2006, 10:49 PM
Quote from: l2k-Shadow on September 12, 2006, 10:38 PM
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?

There is no easy way.  You would have to do some crazy stuff like in this thread (http://forum.valhallalegends.com/index.php?topic=7248.msg65344#msg65344)
Title: Re: calling functions from loaded libraries
Post by: UserLoser on September 12, 2006, 10:50 PM
Quote from: Joex86] link=topic=15673.msg157825#msg157825 date=1158119354]
Why?

Declare Function FunctionName lib "DllName.dll" (Arguments as ArgumentTypes) as ReturnType

Perhaps he wants to call Extrawork or CheckRevision or something similiar in another application.
Title: Re: calling functions from loaded libraries
Post by: l2k-Shadow on September 12, 2006, 11:25 PM
Alright I'll check that out, thanks.
Title: Re: calling functions from loaded libraries
Post by: TheMinistered on September 14, 2006, 06:05 PM
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
Title: Re: calling functions from loaded libraries
Post by: MyndFyre on September 14, 2006, 06:43 PM
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:

__declspec(dllexport) int SFileOpenArchive(char* fileName, HMPQ* mpqHandle);


Visual Basic 2005 can do this:

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


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.  ;)