locked
Callback function from C# to C++ RRS feed

  • Question

  • Hello,

    I have searched on the net, but I haven't found an answer to my problem.

    I have a C++ program (an exe file) and a C# dll. The exe file contains a callback function. I need to send the pointer to the C# dll, in order to call the function back from C#.

    Here is a scenario:

    In the C++ file:

    struct MSG_INFO
    {
        void* caller;        
        char* info;
        long errnum;
    };

    void callback(MSG_INFO* info)
    {
      // do something
    }

    The C# dll should receive the pointer to the callback function from the exe and call it through this pointer. If I use managed C++ instead of C#, everything works perfect. I use .NET 2.0 and Visual Studio 2005.

    A short C# sample of how to receive the pointer to callback function and how to call the function using the pointer would be great.
    Thank you for any help/advice.
    Tuesday, November 20, 2007 7:01 AM

Answers

  • This is fairly simple to do. Just use the Marshal class to generate a delegate for the function. Y ou need to do only two things to get this to work.

    1.  Make sure that the structure has been correctly marshaled in your C# code. You should have a class that looks like this (I'm assuming that "caller" is a pointer to a object here; if this doesn't work, then it should after a little tweaking):


    using System.Runtime.InteropServices;
    [StructLayout(LayoutKind.Sequential)]
    class MSG_INFO
    {
        [MarshalAs(UnmanagedType.LPStruct)]
        public IntPtr caller;

        [MarshalAs(UnmanagedType.LPStr)]
        public string info;

        [MarshalAs(UnmanagedType.I4)]
        public int errnum;
    }

    2.  You need to create a delegate that takes a "pointer" to the structure you just created. You should be able to get away with this.

    delegate void CallbackFunction(MSG_INFO msgInfo);

    3.  The final step is to Marshal the pointer to a Delegate. This is fairly easy. I'm going to assume that you're getting a void pointer and start from there.

        unsafe void InvokeCallback(void* callback, MSG_INFO msgInfo)
        {
            IntPtr ptr = new IntPtr(callback);
            CallbackFunction cbFunc = (CallbackFunction)Marshal.GetDelegateForFunctionPointer(ptr, typeof(CallbackFunction));
            cbFunc(msgInfo);
        }


    That should work fine for you. If it doesn't, we can tweak it a bit. If you've got alot of these callbacks going on, I would suggest that you make/use a generic method for calling the callbacks.





    Wednesday, November 21, 2007 12:12 AM

All replies

  • This is fairly simple to do. Just use the Marshal class to generate a delegate for the function. Y ou need to do only two things to get this to work.

    1.  Make sure that the structure has been correctly marshaled in your C# code. You should have a class that looks like this (I'm assuming that "caller" is a pointer to a object here; if this doesn't work, then it should after a little tweaking):


    using System.Runtime.InteropServices;
    [StructLayout(LayoutKind.Sequential)]
    class MSG_INFO
    {
        [MarshalAs(UnmanagedType.LPStruct)]
        public IntPtr caller;

        [MarshalAs(UnmanagedType.LPStr)]
        public string info;

        [MarshalAs(UnmanagedType.I4)]
        public int errnum;
    }

    2.  You need to create a delegate that takes a "pointer" to the structure you just created. You should be able to get away with this.

    delegate void CallbackFunction(MSG_INFO msgInfo);

    3.  The final step is to Marshal the pointer to a Delegate. This is fairly easy. I'm going to assume that you're getting a void pointer and start from there.

        unsafe void InvokeCallback(void* callback, MSG_INFO msgInfo)
        {
            IntPtr ptr = new IntPtr(callback);
            CallbackFunction cbFunc = (CallbackFunction)Marshal.GetDelegateForFunctionPointer(ptr, typeof(CallbackFunction));
            cbFunc(msgInfo);
        }


    That should work fine for you. If it doesn't, we can tweak it a bit. If you've got alot of these callbacks going on, I would suggest that you make/use a generic method for calling the callbacks.





    Wednesday, November 21, 2007 12:12 AM
  • I hate it when people give half ass solution. It is either they don't know how to do it or they assume people can read their mind.
    Tuesday, July 3, 2018 2:39 PM