Functions with pointer-to-pointer arguments get generated incorrectly
Function arguments that have pointer-to-pointer (eg. https://gstreamer.freedesktop.org/documentation/base/gstpushsrc.html?gi-language=c#GstPushSrcClass::create) seem to get treated as simply a pointer, and end up writing to bad memory.
Example of generated code:
static CreateNativeDelegate Create_cb_delegate;
static CreateNativeDelegate CreateVMCallback {
get {
if (Create_cb_delegate == null)
Create_cb_delegate = new CreateNativeDelegate (Create_cb);
return Create_cb_delegate;
}
}
static void OverrideCreate (GLib.GType gtype)
{
OverrideCreate (gtype, CreateVMCallback);
}
static void OverrideCreate (GLib.GType gtype, CreateNativeDelegate callback)
{
unsafe {
IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("create"));
*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
}
}
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
delegate int CreateNativeDelegate (IntPtr inst, IntPtr buf);
static int Create_cb (IntPtr inst, IntPtr buf)
{
try {
PushSrc __obj = GLib.Object.GetObject (inst, false) as PushSrc;
Gst.FlowReturn __result;
__result = __obj.OnCreate (buf == IntPtr.Zero ? null : (Gst.Buffer) GLib.Opaque.GetOpaque (buf, typeof (Gst.Buffer), false));
return (int) __result;
} catch (Exception e) {
GLib.ExceptionManager.RaiseUnhandledException (e, true);
// NOTREACHED: above call does not return.
throw e;
}
}
[GLib.DefaultSignalHandler(Type=typeof(Gst.Base.PushSrc), ConnectionMethod="OverrideCreate")]
protected virtual Gst.FlowReturn OnCreate (Gst.Buffer buf)
{
return InternalCreate (buf);
}
private Gst.FlowReturn InternalCreate (Gst.Buffer buf)
{
CreateNativeDelegate unmanaged = null;
unsafe {
IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("create"));
unmanaged = (CreateNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(CreateNativeDelegate));
}
if (unmanaged == null) return (Gst.FlowReturn) 0;
int __result = unmanaged (this.Handle, buf == null ? IntPtr.Zero : buf.Handle);
return (Gst.FlowReturn) __result;
}