[Mono-list] How to marshal a native function pointer to a native function with p/invoke?

Ben Henderson bhenderson at ipswitch.com
Mon Mar 23 10:05:50 EDT 2009


I have entered the following defect for this issue:

Bug 487758 - Marshaling a native function pointer to native function call
throws assertion

But, I have also found a work around for the problem.  I'll post it here in
case anyone else runs into this problem.

The work around is:  Create a managed delegate that calls the un-managed
function.  The following code is what I posted in the defect in BugZilla. 
The Workaround class shows how to make it work with the managed delegate,
and the Bug class demonstrates the defect.

using System;
using System.Runtime.InteropServices;

namespace FunctionPointerInterop
{
    class Workaround
    {
        [DllImport("testdll.dll")]
        public extern static void foo();

        [DllImport("testdll.dll")]
        public extern static void bar(foo_delegate foo);

        // Delegate definition
        public delegate void foo_delegate();

        static foo_delegate my_foo_delegate;

        // Managed delegate that calls the native function "foo"
        static void ManagedFooDelegate()
        {
            // Make the native call
            foo();
        }

        public static void Start()
        {
            // Create delegate for managed callback
            my_foo_delegate = new foo_delegate(ManagedFooDelegate);
            // Call native function with managed delegate
            bar(my_foo_delegate);
        }
    }

    class Bug
    {
        [DllImport("testdll.dll")]
        public extern static void foo();

        [DllImport("testdll.dll")]
        public extern static void bar(foo_delegate foo);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void foo_delegate();

        static foo_delegate my_foo_delegate;

        public static void Start()
        {
            // Create delegate with native pointer
            my_foo_delegate = new foo_delegate(foo);
            bar(my_foo_delegate);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Workaround.Start();
            Bug.Start();
        }
    }
}






Ben Henderson wrote:
> 
> Hello all,
> 
> I am having an interesting problem with Mono 2.2 with trying to pass a
> native function pointer to a function in the same native library.  The
> sample code below works with the .NET CLR, but dies in the mono runtime
> with the following assertion/error  (I have also tried changing the
> prototype for the P/Invoke method to use the delegate, but get the same
> assertion when calling the method):
> 
> **
> ERROR:marshal.c:9235:mono_marshal_get_managed_wrapper: assertion failed:
> (!mono_
> method_signature (method)->pinvoke)
> 
> This application has requested the Runtime to terminate it in an unusual
> way.
> Please contact the application's support team for more information.
> **
> 
> So.. my question is...  Am I doing something wrong?  Is this not supported
> in mono?  Is there a workaround for mono (other than LoadLibrary/dlopen)
> -- I would like to utilized managed code to do this and not have to add
> #if's for different platforms!
> 
> Thanks in advance!
> 
> Ben
> 
> ******* Code *******
> 
> TESTDLL.DLL code:
> **************
> #include "stdafx.h"
> #include <stdio.h>
> 
> extern "C" void TESTDLL_EXPORT foo()
> {
> 	printf("foo!\n");
> }
> 
> extern "C" void TESTDLL_EXPORT bar(void (*fn)(void))
> {
> 	if (fn)
> 	{
> 		fn();
> 	}
> }
> 
> Test Program code:
> ***************
> using System;
> using System.Runtime.InteropServices;
> 
> namespace FunctionPointerInterop
> {
>     class Program
>     {
>         [DllImport("testdll.dll")]
>         public extern static void foo();
> 
>         [DllImport("testdll.dll")]
>         public extern static void bar(IntPtr foo);
> 
>         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
>         public delegate void foo_delegate();
> 
>         static foo_delegate my_foo_delegate;
> 
>         static void Main(string[] args)
>         {
>             my_foo_delegate = new foo_delegate(foo);
>             IntPtr ptr =
> Marshal.GetFunctionPointerForDelegate(my_foo_delegate);
>             bar(ptr);
>         }
>     }
> }
> 
> 

-- 
View this message in context: http://www.nabble.com/How-to-marshal-a-native-function-pointer-to-a-native-function-with-p-invoke--tp22608410p22660798.html
Sent from the Mono - General mailing list archive at Nabble.com.



More information about the Mono-list mailing list