Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / September 2004

Tip: Looking for answers? Try searching our database.

ARRRGGGHHHH Function Pointers!!!!

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Mark Olbert - 21 Sep 2004 01:48 GMT
I am totally bollixed up on this one.

If I can marshal a delegate to a legacy DLL as a callback, why the hell can't I do something to a
delegate to assign it to a function pointer variable in a structure?!? It sure seems like the two
operations are very similar; why do I have to cross a DLL boundary to do it?

Does anyone have any suggestions about how to work around this situation? Or should I just check
myself into an asylum right now?

- Mark
Willy Denoyette [MVP] - 23 Sep 2004 21:46 GMT
Maybe this is what you are looking for?

// CS file sample program passing callback function pointers through a
structure
using System;
using System.Runtime.InteropServices;

public delegate void CalcDelegate(int arg1, int arg2);
[StructLayout(LayoutKind.Sequential)]
struct FunctionTable
{
 public IntPtr fAdd;    // function pointer pointing to AddMethod
 public IntPtr fMult;    // function ptr pointing to MultMethod
}
class Tester
{
 [DllImport("native.dll")]
 public static extern void NativeCaller(FunctionTable ft);

 [DllImport("msvcrt")]
 public static extern IntPtr strncpy(Delegate pd, IntPtr src, int size);

 static CalcDelegate pd;
 public static void Main()
 {
  FunctionTable ft = new FunctionTable();

  pd = new CalcDelegate(AddMethod);
  ft.fAdd = GetFunctionPtrFromDelegate(pd);
  pd = new CalcDelegate(MultMethod);
  ft.fMult = GetFunctionPtrFromDelegate(pd);
  NativeCaller(ft);
 }
 // here is the trick, we use a msvcrt function to return a pointer from
the delegate
 static IntPtr GetFunctionPtrFromDelegate(Delegate d)
 {
  // strncpy returns the buffer address (the marshaled delegate pointer).
We obviously don't copy anything
  return strncpy(d, IntPtr.Zero, 0);
 }

 static void AddMethod(int arg1, int arg2)
 {
  Console.WriteLine(arg1 + arg2);

 }
 static void MultMethod(int arg1, int arg2)
 {
  Console.WriteLine(arg1 * arg2);
 }
}

//C++ file native.cpp
// compile with: cl /LD native.cpp
struct FunctionTable
{
  void* fAdd;
  void* fMult;
};
  typedef int (__stdcall *FPTRHELPER) (int, int);

extern "C" {
__declspec(dllexport) void  NativeCaller (FunctionTable);
}

void NativeCaller(FunctionTable fptr)
{

(*(FPTRHELPER)fptr.fAdd)(5, 2);
(*(FPTRHELPER)fptr.fMult)(5, 2);

}

Willy.

>I am totally bollixed up on this one.
>
[quoted text clipped - 10 lines]
>
> - Mark
Girish Bharadwaj - 23 Sep 2004 22:20 GMT
brrr....  That is some code. :) love it.

Signature

Girish Bharadwaj
http://msmvps.com/gbvb

> Maybe this is what you are looking for?
>
[quoted text clipped - 86 lines]
> >
> > - Mark
Girish bharadwaj - 24 Sep 2004 03:03 GMT
BTW: If you want to get the IntPtr for a delegate, you can do that by

IntPtr funcPtr = d.Method.MethodBase.GetFunctionPointer(); //d= delegate, So
you dont have to resort to strncpy hack :)

Signature

Girish Bharadwaj
http://msmvps.com/gbvb

> brrr....  That is some code. :) love it.
>
[quoted text clipped - 90 lines]
> > >
> > > - Mark
Willy Denoyette [MVP] - 24 Sep 2004 10:12 GMT
Girish,

Unfortunately this doesn't work:
1. d.Method.MethodBase.GetFunctionPointer(); doesn't compile because
MethodBase is no property of MethodInfo, GetFunctionPointer is a method of
RuntimeMethodHandle. So you have to use - IntPtr f =
d.Method.MethodHandle.GetFunctionPointer(); but read on...

2. The MethodHandle (RuntimeMethodHandle) is only valid in the domain in
which he is obtained!
Normally, when unmanaged code (process wide) "calls back" into managed code
the PInvoke thunk (or IJW thunk) selects the target domain, based on flags
set in the VTFixup table entries when you first call into unmanaged code
(passing a delegate as arg), and adjusts the delegate callback method
pointer accordingly. That's the reason why you need to call into unmanaged
code passing a delegate to get a correctly adjusted method pointer back.
When using the function pointer returned from GetFunctionPointer() will most
probably call at the wrong address (corrupting the stack) or call into
read-only memory.

Willy.

> BTW: If you want to get the IntPtr for a delegate, you can do that by
>
[quoted text clipped - 102 lines]
>> > >
>> > > - Mark
Girish bharadwaj - 24 Sep 2004 11:26 GMT
Doh! for 1. Yeah. I meant MethodHandle.
So Doh! for 2. I did not realize that part. :)

Signature

Girish Bharadwaj
http://msmvps.com/gbvb

> Girish,
>
[quoted text clipped - 124 lines]
> >> > >
> >> > > - Mark
Willy Denoyette [MVP] - 24 Sep 2004 11:28 GMT
> Girish,

> probably call at the wrong address (corrupting the stack) or call into
> read-only memory.

Woops... should read:

.... or call into protected memory.

Willy.
Girish bharadwaj - 24 Sep 2004 11:39 GMT
There is a Marshal.GetFunctionPointerForDelegate() in 2.0. Is that similar
to what you are describing?

Signature

Girish Bharadwaj
http://msmvps.com/gbvb

>
> > Girish,
[quoted text clipped - 7 lines]
>
> Willy.
Willy Denoyette [MVP] - 24 Sep 2004 16:05 GMT
> There is a Marshal.GetFunctionPointerForDelegate() in 2.0. Is that similar
> to what you are describing?

Girish,

Absolutely, GetFunctionPointerForDelegate() (internal)calls into the CLR 2.0
and returns a valid pointer to be used as callback pointer for the target
domain.

Willy.
Mark Olbert - 28 Sep 2004 04:43 GMT
Wow! Thanx for the solution/hack, and for the sidebar discussion.

- Mark

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.