using System; using System.Runtime.InteropServices; public class Widget { IntPtr rawObject; public delegate void virtualMethod1Delegate(); public delegate void virtualMethod2Delegate(); virtualMethod1Delegate vm1Delegate; virtualMethod2Delegate vm2Delegate; [DllImport("libwidget", CharSet=CharSet.Ansi)] private static extern IntPtr new_WidgetBridge( [MarshalAs(UnmanagedType.FunctionPtr)] virtualMethod1Delegate d1, [MarshalAs(UnmanagedType.FunctionPtr)] virtualMethod2Delegate d2 ); public Widget() { vm1Delegate = new virtualMethod1Delegate( VirtualMethod1 ); vm2Delegate = new virtualMethod2Delegate( VirtualMethod2 ); rawObject = new_WidgetBridge( vm1Delegate, vm2Delegate ); } [DllImport("libwidget", CharSet=CharSet.Ansi)] private static extern void Widget_virtualMethod1(IntPtr instPointer); public virtual void VirtualMethod1() { Widget_virtualMethod1(rawObject); } [DllImport("libwidget", CharSet=CharSet.Ansi)] private static extern void Widget_virtualMethod2(IntPtr instPointer); public virtual void VirtualMethod2() { Widget_virtualMethod2(rawObject); } [DllImport("libwidget", CharSet=CharSet.Ansi)] private static extern void WidgetBridge_doSomething(IntPtr instPointer); public virtual void DoSomething() { WidgetBridge_doSomething(rawObject); } } public class CustomWidget: Widget { public CustomWidget(): base() {} public override void VirtualMethod2() { Console.WriteLine("C# version of VirtualMethod2"); } } public class Testing { public static void Main() { Widget w = new CustomWidget(); w.DoSomething(); Environment.Exit(0); } }