|
-
Apr 3rd, 2011, 05:29 PM
#1
Thread Starter
Junior Member
[RESOLVED] How to use LoadLibrary()/GetProcAddress()?
Hey -
The following code works great to interface *.dll that I built in Ada from VB.NET (2008) ...
Private Declare Function TestDelegate Lib "C:\ABC.dll" Alias "Test" _
(ByVal A As Single, _
ByVal B As Integer, _
ByVal C As String, _
ByRef D As TestType) As Single
... where TestType is a struct. The only problem I have with this is that the *.dll and its path has to be hard coded.
So I started looking at using LoadLibrary() and GetProcAddress(). I figured out the following interfaces ...
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Function LoadLibrary(<[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpFileName As String) As IntPtr
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
Public Function GetProcAddress(<[In]()> ByVal hModule As IntPtr, <[In](), MarshalAs(UnmanagedType.LPStr)> ByVal lpProcName As String) As IntPtr
End Function
... that I can call like ...
Dim lLibraryHandle As IntPtr = LoadLibrary("C:\ABC.dll")
Dim lFunctionHandle As IntPtr = GetProcAddress(lLibraryHandle, "Test")
I check for IntPtr.Zero to make sure this all worked but now the question is how can I actually use the lFunctionHandle to call Test()? Has somebody worked
with this before?
I'm also curious what the difference is between the <DllImport("kernel32.dll" ... and something like Private Declare Function ABC Lib "kernel32" (...) As XYZ to interface a *.dll?
My last question is whether it is necessary to call FreeLibrary() or whether VB will handle freeing up the memory?
Thanks,
Joe
-
Apr 3rd, 2011, 05:58 PM
#2
Fanatic Member
Re: How to use LoadLibrary()/GetProcAddress()?
After a quick search I found this:
http://www.codeproject.com/KB/cs/dyninvok.aspx
You seem to have to use "InvokeFunc" API to do what you want:
Code:
<DllImport("Invoke", CharSet:=CharSet.Unicode)]
Public Shared Function InvokeFunc(ByVal funcptr As IntPtr, ByVal hwnd As IntPtr, ByVal message As String, ByVal title As String, ByVal flags As Integer) As Integer
And yes it is wise to call FreeLibrary, since it frees the resources so other programs (including Windows for file move/delete/rename) can access the files.
-
Apr 3rd, 2011, 06:51 PM
#3
Thread Starter
Junior Member
Re: How to use LoadLibrary()/GetProcAddress()?
Yeah ... most examples I found were in C# but I finally came across something that uses the Invoke() as you suggested ...
http://msdn.microsoft.com/en-us/libr...er(VS.80).aspx
I started to play with this and it looks very promosing ... thanks!
Joe
-
Apr 4th, 2011, 07:38 AM
#4
Re: How to use LoadLibrary()/GetProcAddress()?
One cool related project is the P/Invoke Interop Assistant.
-
Apr 4th, 2011, 09:22 AM
#5
Thread Starter
Junior Member
Re: How to use LoadLibrary()/GetProcAddress()?
Hey -
I installed the PInvoke Interop Assistant but it will not work with the *.dll as it does not have an asssembly manifest.
Joe
-
Apr 4th, 2011, 09:39 AM
#6
Re: How to use LoadLibrary()/GetProcAddress()?
That's right. I was referring to the PInvoke functionality which can help you figure out the method signature in C# and VB.Net.
-
Apr 4th, 2011, 11:58 AM
#7
Thread Starter
Junior Member
Re: How to use LoadLibrary()/GetProcAddress()?
Nice tool and I will definitely keep it in mind next time I run into a similar problem. As to my current problem, I actually figured out how to make it work:
The problem was with the "CharSet.Unicode" in ...
<UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Unicode)> _
Delegate Function XYZ ...
... I guess the Ada *.dll was not happy about the String being passed in four times the size it expected. I changed that to "CharSet.Ansi" and it is now working beautifully!
Thanks!
Joe
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|