diff --git a/Source/Libs/GLibSharp/AbiStructExtensions.cs b/Source/Libs/GLibSharp/AbiStructExtensions.cs new file mode 100644 index 000000000..0d5465eb9 --- /dev/null +++ b/Source/Libs/GLibSharp/AbiStructExtensions.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.InteropServices; + +namespace GLib +{ + + public static class AbiStructExtension + { + public static N BaseOverride(this AbiStruct class_abi, GType gtype, string fieldname) where N : Delegate + { + N unmanaged = null; + unsafe { + IntPtr raw_ptr = IntPtr.Zero; + while (raw_ptr == IntPtr.Zero && GType.IsManaged(gtype)) { + gtype = gtype.GetThresholdType(); + var abi_ptr = (IntPtr*) (((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset(fieldname)); + raw_ptr = *abi_ptr; + } + + if (raw_ptr != IntPtr.Zero) { + unmanaged = Marshal.GetDelegateForFunctionPointer(raw_ptr); + } + } + + return unmanaged; + } + } +} \ No newline at end of file diff --git a/Source/Tools/GapiCodegen/GObjectVM.cs b/Source/Tools/GapiCodegen/GObjectVM.cs index c7d83a762..8de8119fd 100644 --- a/Source/Tools/GapiCodegen/GObjectVM.cs +++ b/Source/Tools/GapiCodegen/GObjectVM.cs @@ -207,11 +207,7 @@ namespace GtkSharp.Generation { this.GenerateMethodBody (sw, null); // Find the first unmanaged ancestor - sw.WriteLine ("\t\t\t{0}NativeDelegate unmanaged = null;", Name); - sw.WriteLine ("\t\t\tunsafe {"); - sw.WriteLine ("\t\t\t\tIntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset(\"{0}\"));", CName); - sw.WriteLine ("\t\t\t\tunmanaged = ({0}NativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof({0}NativeDelegate));", this.Name); - sw.WriteLine ("\t\t\t}"); + sw.WriteLine ($"\t\t\t{Name}NativeDelegate unmanaged = class_abi.BaseOverride<{Name}NativeDelegate>(this.LookupGType(), \"{CName}\");"); sw.Write ("\t\t\tif (unmanaged == null) "); if (parms.HasOutParam) sw.WriteLine ("throw new InvalidOperationException (\"No base method to invoke\");"); diff --git a/Source/Tools/GapiCodegen/ObjectGen.cs b/Source/Tools/GapiCodegen/ObjectGen.cs index 5a34ff15a..8b78a61f3 100644 --- a/Source/Tools/GapiCodegen/ObjectGen.cs +++ b/Source/Tools/GapiCodegen/ObjectGen.cs @@ -147,6 +147,7 @@ namespace GtkSharp.Generation { sw.WriteLine ("\tusing System.Collections;"); sw.WriteLine ("\tusing System.Collections.Generic;"); sw.WriteLine ("\tusing System.Runtime.InteropServices;"); + sw.WriteLine ("\tusing static GLib.AbiStructExtension;"); sw.WriteLine (); SymbolTable table = SymbolTable.Table;