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?
Why?
Declare Function FunctionName lib "DllName.dll" (Arguments as ArgumentTypes) as ReturnType
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)
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.
Alright I'll check that out, thanks.
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
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. ;)