0 out of 1 rated this helpful - Rate this topic

Marshal.GetDelegateForFunctionPointer Method

Converts an unmanaged function pointer to a delegate.

Namespace:  System.Runtime.InteropServices
Assembly:  mscorlib (in mscorlib.dll)
public static Delegate GetDelegateForFunctionPointer(
	IntPtr ptr,
	Type t
)

Parameters

ptr
Type: System.IntPtr
The unmanaged function pointer to be converted.
t
Type: System.Type
The type of the delegate to be returned.

Return Value

Type: System.Delegate
A delegate instance that can be cast to the appropriate delegate type.
Exception Condition
ArgumentException

The t parameter is not a delegate or is generic.

ArgumentNullException

The ptr parameter is null.

-or-

The t parameter is null.

In versions 1.0 and 1.1 of the .NET Framework, it was possible to pass a delegate representing a managed method to unmanaged code as a function pointer, allowing the unmanaged code to call the managed method through the function pointer. It was also possible for the unmanaged code to pass that function pointer back to the managed code, and the pointer was resolved properly to the underlying managed method.

In the .NET Framework 2.0 and later versions, you can use the GetDelegateForFunctionPointer and GetFunctionPointerForDelegate methods to marshal delegates in both directions. With GetDelegateForFunctionPointer, ptr is imported as a System.IntPtr. A System.IntPtr can be obtained for a managed delegate by calling GetFunctionPointerForDelegate and passed as a parameter; it can then be called from inside the unmanaged method. Note that the parameter marshaler can also marshal function pointers to delegates in the .NET Framework 2.0 and later versions.

The GetDelegateForFunctionPointer method has the following restrictions:

  • Generics are not supported in interop scenarios.

  • You cannot pass an invalid function pointer to this method.

  • You can use this method only for pure unmanaged function pointers.

  • You cannot use this method with function pointers obtained through C++ or from the GetFunctionPointer method.

  • You cannot use this method to create a delegate from a function pointer to another managed delegate.

.NET Framework

Supported in: 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1
  • SecurityCriticalAttribute  

    requires full trust for the immediate caller. This member cannot be used by partially trusted or transparent code.

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
You can get it to work with any calling convention

@Andre

You can specifiy any calling convention. What you need to do is add the UnmanagedFunctionPointer attributute to your delegate declaration, like this:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void MyHandler();



EDIT: I just noticed that Vozzie said essentially the same thing with the VB sample.

VB.Net sample
Imports System.Runtime.InteropServices

Friend Class EntryPoint

Class NativeMethods
Private Const KERNEL32_DLL As String = "Kernel32.dll"
<DllImport(KERNEL32_DLL)> _
Friend Shared Function LoadLibrary(ByVal szFileName As String) As IntPtr
End Function
<DllImport(KERNEL32_DLL)> _
Friend Shared Function GetProcAddress(ByVal hLibrary As IntPtr, ByVal szProcName As String) As IntPtr
End Function
<DllImport(KERNEL32_DLL)> _
Friend Shared Function FreeLibrary(ByVal hLibrary As IntPtr) As Integer
End Function
End Class

<UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Unicode)> _
Delegate Function MessageBoxProto(ByVal hWndParent As IntPtr, ByVal szText As String, ByVal szTitle As String, ByVal ulFlags As UInt32) As Integer

Friend Shared Sub Main()

Dim hUser32 As IntPtr = NativeMethods.LoadLibrary("User32.dll")
Dim pMethod As IntPtr = NativeMethods.GetProcAddress(hUser32, "MessageBoxW")
Dim MessageBox As MessageBoxProto = DirectCast(System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(pMethod, GetType(MessageBoxProto)), MessageBoxProto)
MessageBox.Invoke(IntPtr.Zero, "hello there", "cool!", Convert.ToUInt32(MsgBoxStyle.Information Or MsgBoxStyle.SystemModal))
NativeMethods.FreeLibrary(hUser32)

End Sub

End Class

Supports stdcall only
If you're trying use GetDelegateforFunctionPointer to call a native API that uses the CDECL calling convention, don't bother.  It will fail when you try to call the native function using the pointer.  You'll have to use a normal PInvoke call, and specify CallingConvention = CallingConvention.Cdecl in the DllImport attribute.