AbiStructExtension.BaseOverride: introduce an Extension to find the first overriden method in a base-class, even if a overriden class doesn't override the base class & change to GapiCodegen to use this extension

This commit is contained in:
lytico 2020-04-06 22:31:10 +02:00
parent 34ab03a3c2
commit c6cfc9d58c
3 changed files with 30 additions and 5 deletions

View File

@ -0,0 +1,28 @@
using System;
using System.Runtime.InteropServices;
namespace GLib
{
public static class AbiStructExtension
{
public static N BaseOverride<N>(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<N>(raw_ptr);
}
}
return unmanaged;
}
}
}

View File

@ -207,11 +207,7 @@ namespace GtkSharp.Generation {
this.GenerateMethodBody (sw, null); this.GenerateMethodBody (sw, null);
// Find the first unmanaged ancestor // Find the first unmanaged ancestor
sw.WriteLine ("\t\t\t{0}NativeDelegate unmanaged = null;", Name); sw.WriteLine ($"\t\t\t{Name}NativeDelegate unmanaged = class_abi.BaseOverride<{Name}NativeDelegate>(this.LookupGType(), \"{CName}\");");
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.Write ("\t\t\tif (unmanaged == null) "); sw.Write ("\t\t\tif (unmanaged == null) ");
if (parms.HasOutParam) if (parms.HasOutParam)
sw.WriteLine ("throw new InvalidOperationException (\"No base method to invoke\");"); sw.WriteLine ("throw new InvalidOperationException (\"No base method to invoke\");");

View File

@ -147,6 +147,7 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\tusing System.Collections;"); sw.WriteLine ("\tusing System.Collections;");
sw.WriteLine ("\tusing System.Collections.Generic;"); sw.WriteLine ("\tusing System.Collections.Generic;");
sw.WriteLine ("\tusing System.Runtime.InteropServices;"); sw.WriteLine ("\tusing System.Runtime.InteropServices;");
sw.WriteLine ("\tusing static GLib.AbiStructExtension;");
sw.WriteLine (); sw.WriteLine ();
SymbolTable table = SymbolTable.Table; SymbolTable table = SymbolTable.Table;