Problems using Marshal.GetDelegateForFunctionPointer.DynamicInvoke() and pointers

P

Paul Coene

I've spent the better part of the day trying to figure out how to utilize
an unmanaged DLL dynamically from VB.Net. I've figured out how to get the
library loaded, and set up delegates for the DLL.

What I can't get to work, or see how to do, is pass arguments to
DynamicInvoke that will get filled in. The DLL API wants long * to fill
in

My example below:

Private Declare Auto Function LoadLibrary Lib "kernel32.dll" (ByVal
ProcName As String) As Integer Private Declare Ansi Function
GetProcAddress Lib "kernel32.dll" (ByVal ModuleHandle As Integer, ByVal
ProcName As String) As Integer

Private Delegate Function dPassThruOpen(ByRef reserved As Integer,
ByRef DeviceId As Integer) As Integer

....

Dim ModuleHandle As Integer
Dim OpenMethodPointer As Integer
Dim temp As Integer
Dim ret As Long
Dim arg() As Object
Dim deviceId As Integer

ModuleHandle = LoadLibrary(myInstance.dllpath)
OpenMethodPointer = GetProcAddress(ModuleHandle, "PassThruOpen")
temp = 0
arg = New Object() {temp, deviceId}
ret = Marshal.GetDelegateForFunctionPointer(OpenMethodPointer,GetType(dPassThruOpen)).DynamicInvoke(arg)
ke(arg)

......

The above gets a valid ModuleHandle. A Valid OpenMethodPointer. The call to DynamicInvoke succeeds
and the ret provided makes sense (as it would have come from the DLL). However, the deviceId is not
filled in. What am I doing wrong?
 
C

Claes Bergefall

I can't see anything immediately wrong. You're using Integer where you
should have IntPtr in a bunch of places, but I'm not sure if that's what
causes your problems. See if the code below makes any difference. I suggest
you turn on option strict and option explicit in any case.

Can you show us the exact signature for the PassThruOpen method that you're
trying to call (I'm guessing that it's a C/C++ method)?

---
Private Declare Auto Function LoadLibrary Lib "kernel32.dll" (ByVal FileName
As String) As IntPtr
Private Declare Auto Function GetProcAddress Lib "kernel32.dll" (ByVal
ModuleHandle As IntPtr, ByVal ProcName As String) As IntPtr
Private Delegate Function dPassThruOpen(ByRef reserved As Integer, ByRef
DeviceId As Integer) As Integer

Dim ModuleHandle As IntPtr
Dim OpenMethodPointer As IntPtr
Dim temp As Integer
Dim deviceId As Integer
Dim arg() As Object
Dim ret As Integer

ModuleHandle = LoadLibrary(myInstance.dllpath)
OpenMethodPointer = GetProcAddress(ModuleHandle, "PassThruOpen")
temp = 0
arg = New Object() {temp, deviceId}
ret = Marshal.GetDelegateForFunctionPointer(OpenMethodPointer,
GetType(dPassThruOpen)).DynamicInvoke(arg)

/claes
 
H

Herfried K. Wagner [MVP]

Paul Coene said:
I've spent the better part of the day trying to figure out how to utilize
an unmanaged DLL dynamically from VB.Net. I've figured out how to get the
library loaded, and set up delegates for the DLL.

What I can't get to work, or see how to do, is pass arguments to
DynamicInvoke that will get filled in. The DLL API wants long * to fill
in

My example below:

Private Declare Auto Function LoadLibrary Lib "kernel32.dll" (ByVal
ProcName As String) As Integer Private Declare Ansi Function
GetProcAddress Lib "kernel32.dll" (ByVal ModuleHandle As Integer, ByVal
ProcName As String) As Integer

Private Delegate Function dPassThruOpen(ByRef reserved As Integer,
ByRef DeviceId As Integer) As Integer

In addition to Claes' reply:

Mark 'DeviceId' as 'Out':

\\\
Private Delegate Function dPassThruOpen( _
<Out()> ByRef DeviceId As Int32 _
) As Int32
///

In addition, mark 'In' parameters using '<[In]()>' in the delegates.
 
P

Paul Coene

I can't see anything immediately wrong. You're using Integer where you
should have IntPtr in a bunch of places, but I'm not sure if that's what
causes your problems. See if the code below makes any difference. I suggest
you turn on option strict and option explicit in any case.

Can you show us the exact signature for the PassThruOpen method that you're
trying to call (I'm guessing that it's a C/C++ method)?

There was no problem other than I was so focused on learning that
I didn't see I had it right. The ParamArray values WERE getting updated.
For some reason, I was examining the variables I had put into
the array.... silly...

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top