Matt Gieselman | Unmanaged to managed callbacks in C#

Unmanaged to managed callbacks in C#

To have unmanaged code callback to C# you can provide a pointer to the callback and the CLR does the rest.

Another useful trick is to pin an object using GCHandle.Alloc(obj, GCHandleType.Pinned) and have the unmanaged code return that pointer in the callback, you can then call the corresponding method on the object.

using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;

namespace UnmanagedCallbackExample
{
    internal class Program
    {
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate IntPtr CallbackHandler(IntPtr bitmap);

        [DllImport("UnmanagedLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int StartThread(CallbackHandler callback);

        private static IntPtr _pointer = IntPtr.Zero;
        private static int _callbackCount = 0;

        private static void Main(string[] args)
        {
            _pointer = Marshal.AllocHGlobal(64);

            Debug.Assert(StartThread(Callback) == 42);

            Console.WriteLine("Press any key to exit.");
            Console.Read();
        }

        public static IntPtr Callback(IntPtr bitmap)
        {
            _callbackCount++;
            Console.WriteLine(string.Format("Callback #{0}", _callbackCount));
            
            var managedBitmap = Image.FromHbitmap(bitmap);

            return _pointer;
        }
    }
}

 

UnmanagedCallbackExample.zip (30.7KB)

Comments are closed