By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,385 Members | 1,094 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,385 IT Pros & Developers. It's quick & easy.

WinAPI that returns a funtion ptr

P: n/a
Hello,

I was translating some sample from MSDN from C to VB .NET, and got the
following:

~
Private Declare Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As
IntPtr, <MarshalAs(UnmanagedType.LPStr)> ByVal lpProcName As String) As
<MarshalAs(UnmanagedType.FunctionPtr)> DLLGETVERSIONPROC

Private Delegate Function DLLGETVERSIONPROC(ByRef dvi As DLLVERSIONINFO) As
Integer
Private Function GetDllVersion(ByVal lpszDllName As String) As Integer

Dim hinstDll As IntPtr

Dim dwVersion As Integer = 0

hinstDll = LoadLibrary(lpszDllName)

If hinstDll.ToInt32 <> 0 Then

Dim pDllGetVersion As DLLGETVERSIONPROC

pDllGetVersion = GetProcAddress(hinstDll, "DllGetVersion")

If Not pDllGetVersion Is Nothing Then

Dim dvi As DLLVERSIONINFO

Dim hr As Integer

dvi.cbSize = Marshal.SizeOf(dvi)

hr = pDllGetVersion.Invoke(dvi)

If SUCCEEDED(hr) Then

dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion)

End If

End If

FreeLibrary(hinstDll)

End If

Return dwVersion

End Function

~

When I call this function, an error box pops out:

An unhandled exception of type 'System.ArgumentException' occurred in
WinApp.exe
Additional information: ń┼╠┼ă┴ď ╬┼ ˤ┌─┴╠ Ň╦┴┌┴ď┼╠ě ╬┴ ĂŇ╬╦├╔└.
(Translation: Delegate haven't created the function pointer.)

If I declare GetProcAddress as Integer it returns normal value, so it's
probably a marshalling problem.
Can I do something to get a delegate value?

Thanks in advance.
Nov 21 '05 #1
Share this Question
Share on Google+
8 Replies

P: n/a
>Can I do something to get a delegate value?

No, in .NET v1.x this is not supported.

Mattias

--
Mattias Sj÷gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 21 '05 #2

P: n/a
> No, in .NET v1.x this is not supported.

Bad, bad, too bad... 8=[
Is there another approach?
Nov 21 '05 #3

P: n/a
Is there another approach?


Here's one way

http://www.msjogren.net/dotnet/eng/s...dynpinvoke.asp

Mattias

--
Mattias Sj÷gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 21 '05 #4

P: n/a
Thanks for great sample. Though, my actual question was: can I execute
function whose address was given by API function.

By the way, can I define a ByRef parameter using this MethodBuilder
approach, or I should define it as IntPtr and use GCHandles for getting an
address?

Thanks
Nov 21 '05 #5

P: n/a
>Thanks for great sample. Though, my actual question was: can I execute
function whose address was given by API function.
Not in VB.NET v7.x you can't. Other languages such as C++ and IL
assembler lets you do it though. And in v2.0 of the framework there's
a way to create a delegate for an arbitrary functon pointer.

By the way, can I define a ByRef parameter using this MethodBuilder
approach, or I should define it as IntPtr and use GCHandles for getting an
address?


Yes you can, but to create a ByRef Type in v1.x of the framework you
have to pass the typename with a "&" appended to
System.Type.GetType().

Mattias

--
Mattias Sj÷gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 21 '05 #6

P: n/a
Thanks Mattias.

Unfortunately I can't get the ByRef parameter to pass value back. I call

Dim RetVal As Integer = CInt(t.InvokeMember("DllGetVersion",
BindingFlags.InvokeMethod, Nothing, Activator.CreateInstance(t), New
Object() {dvi})),
where t is Type object.

RetVal equals to 0, so function succeeds, but dvi (DLLVERSIONINFO structure)
doesn't have any members changed.

How can I get it passed?

Thanks again.

"Mattias Sj÷gren" <ma********************@mvps.org> ???????/???????? ?
???????? ?????????: news:eG**************@tk2msftngp13.phx.gbl...
Thanks for great sample. Though, my actual question was: can I execute
function whose address was given by API function.


Not in VB.NET v7.x you can't. Other languages such as C++ and IL
assembler lets you do it though. And in v2.0 of the framework there's
a way to create a delegate for an arbitrary functon pointer.

By the way, can I define a ByRef parameter using this MethodBuilder
approach, or I should define it as IntPtr and use GCHandles for getting anaddress?


Yes you can, but to create a ByRef Type in v1.x of the framework you
have to pass the typename with a "&" appended to
System.Type.GetType().

Mattias

--
Mattias Sj÷gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 21 '05 #7

P: n/a
>Unfortunately I can't get the ByRef parameter to pass value back. I call

Dim RetVal As Integer = CInt(t.InvokeMember("DllGetVersion",
BindingFlags.InvokeMethod, Nothing, Activator.CreateInstance(t), New
Object() {dvi})),
where t is Type object.

RetVal equals to 0, so function succeeds, but dvi (DLLVERSIONINFO structure)
doesn't have any members changed.

How can I get it passed?


If dvi is a strucure variable you have to do

Dim args As New Object() {dvi}
.... t.InvokeMember("DllGetVersion", ..., args)
dvi = CType(args(0), DLLVERSIONINFO)

Mattias

--
Mattias Sj÷gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 21 '05 #8

P: n/a
It works now!

Big thanks for that and for all your patience.

Roman

"Mattias Sj÷gren" <ma********************@mvps.org> ???????/???????? ?
???????? ?????????: news:Oy**************@tk2msftngp13.phx.gbl...
Unfortunately I can't get the ByRef parameter to pass value back. I call

Dim RetVal As Integer = CInt(t.InvokeMember("DllGetVersion",
BindingFlags.InvokeMethod, Nothing, Activator.CreateInstance(t), New
Object() {dvi})),
where t is Type object.

RetVal equals to 0, so function succeeds, but dvi (DLLVERSIONINFO structure)doesn't have any members changed.

How can I get it passed?


If dvi is a strucure variable you have to do

Dim args As New Object() {dvi}
... t.InvokeMember("DllGetVersion", ..., args)
dvi = CType(args(0), DLLVERSIONINFO)

Mattias

--
Mattias Sj÷gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 21 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.