/* Creates a callback method which invokes the corresponding virtual method * @implementor is the class that implements the virtual method(e.g. the class that derives from an interface) or NULL if containing and declaring type are equal */ public void GenerateCallback(StreamWriter sw, ClassBase implementor) { if (!Validate()) { return; } string native_signature = ""; if (!IsStatic) { native_signature += "IntPtr inst"; if (parms.Count > 0) { native_signature += ", "; } } if (parms.Count > 0) { native_signature += parms.ImportSignature; } sw.WriteLine("\t\t[GLib.CDeclCallback]"); sw.WriteLine("\t\tdelegate {0} {1}NativeDelegate ({2});", retval.ToNativeType, this.Name, native_signature); sw.WriteLine(); sw.WriteLine("\t\tstatic {0} {1}_cb ({2})", retval.ToNativeType, this.Name, native_signature); sw.WriteLine("\t\t{"); string unconditional = call.Unconditional("\t\t\t"); if (unconditional.Length > 0) { sw.WriteLine(unconditional); } sw.WriteLine("\t\t\ttry {"); if (!this.IsStatic) { string type; if (implementor != null) { type = implementor.QualifiedName; } else if (this.container_type is InterfaceGen) { type = this.container_type.Name + "Implementor"; // We are in an interface/adaptor, invoke the method in the implementor class } else { type = this.container_type.Name; } sw.WriteLine("\t\t\t\t{0} __obj = GLib.Object.GetObject (inst, false) as {0};", type); } sw.Write(call.Setup("\t\t\t\t")); sw.Write("\t\t\t\t"); if (!retval.IsVoid) { sw.Write(retval.CSType + " __result = "); } if (!this.IsStatic) { sw.Write("__obj."); } sw.WriteLine(this.CallString + ";"); sw.Write(call.Finish("\t\t\t\t")); if (!retval.IsVoid) { sw.WriteLine("\t\t\t\treturn " + retval.ToNative("__result") + ";"); } bool fatal = parms.HasOutParam || !retval.IsVoid; sw.WriteLine("\t\t\t} catch (Exception e) {"); sw.WriteLine("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");"); if (fatal) { sw.WriteLine("\t\t\t\t// NOTREACHED: above call does not return."); sw.WriteLine("\t\t\t\tthrow e;"); } sw.WriteLine("\t\t\t}"); sw.WriteLine("\t\t}"); sw.WriteLine(); }
/* Creates a callback method which invokes the corresponding virtual method * @implementor is the class that implements the virtual method(e.g. the class that derives from an interface) or NULL if containing and declaring type are equal */ public void GenerateCallback (StreamWriter sw, ClassBase implementor) { LogWriter log = new LogWriter (); log.Type = container_type.QualifiedName; if (!Validate (log)) return; string native_signature = ""; if (!IsStatic) { native_signature += "IntPtr inst"; if (parms.Count > 0) native_signature += ", "; } if (parms.Count > 0) native_signature += parms.ImportSignature; sw.WriteLine ("\t\t[UnmanagedFunctionPointer (CallingConvention.Cdecl)]"); sw.WriteLine ("\t\tdelegate {0} {1}NativeDelegate ({2});", retval.ToNativeType, this.Name, native_signature); sw.WriteLine (); sw.WriteLine ("\t\tstatic {0} {1}_cb ({2})", retval.ToNativeType, this.Name, native_signature); sw.WriteLine ("\t\t{"); string unconditional = call.Unconditional ("\t\t\t"); if (unconditional.Length > 0) sw.WriteLine (unconditional); sw.WriteLine ("\t\t\ttry {"); if (!this.IsStatic) { string type; if (implementor != null) type = implementor.QualifiedName; else if (this.container_type is InterfaceGen) // We are in an interface/adaptor, invoke the method in the implementor class type = (this.container_type as InterfaceGen).ImplementorName; else type = this.container_type.Name; sw.WriteLine ("\t\t\t\t{0} __obj = GLib.Object.GetObject (inst, false) as {0};", type); } string indent = "\t\t\t\t"; if (!retval.IsVoid) sw.WriteLine (indent + retval.CSType + " __result;"); sw.Write (call.Setup (indent)); sw.Write (indent); if (!retval.IsVoid) sw.Write ("__result = "); if (!this.IsStatic) sw.Write ("__obj."); sw.WriteLine (this.CallString + ";"); sw.Write (call.Finish (indent)); if (!retval.IsVoid) sw.WriteLine ("\t\t\t\treturn " + retval.ToNative ("__result") + ";"); bool fatal = parms.HasOutParam || !retval.IsVoid; sw.WriteLine ("\t\t\t} catch (Exception e) {"); sw.WriteLine ("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");"); if (fatal) { sw.WriteLine ("\t\t\t\t// NOTREACHED: above call does not return."); sw.WriteLine ("\t\t\t\tthrow e;"); } if (call.HasDisposeParam) { sw.WriteLine ("\t\t\t} finally {"); sw.Write (call.DisposeParams (indent)); } sw.WriteLine ("\t\t\t}"); sw.WriteLine ("\t\t}"); sw.WriteLine (); }
public string GenWrapper(GenerationInfo gen_info) { string wrapper = Name + "Native"; string qualname = MarshalType; if (!Validate()) { return(String.Empty); } body = new MethodBody(parms); StreamWriter save_sw = gen_info.Writer; StreamWriter sw = gen_info.Writer = gen_info.OpenStream(qualname); sw.WriteLine("namespace " + NS + "Sharp {"); sw.WriteLine(); sw.WriteLine("\tusing System;"); sw.WriteLine("\tusing System.Runtime.InteropServices;"); sw.WriteLine(); sw.WriteLine("#region Autogenerated code"); sw.WriteLine("\t[UnmanagedFunctionPointer (CallingConvention.Cdecl)]"); sw.WriteLine("\tinternal delegate " + retval.MarshalType + " " + wrapper + "(" + parms.CallbackImportSignature + ");"); sw.WriteLine(); GenInvoker(gen_info, sw); sw.WriteLine("\tinternal class " + Name + "Wrapper {"); sw.WriteLine(); ManagedCallString call = new ManagedCallString(parms, false); sw.WriteLine("\t\tpublic " + retval.MarshalType + " NativeCallback (" + parms.CallbackImportSignature + ")"); sw.WriteLine("\t\t{"); string unconditional = call.Unconditional("\t\t\t"); if (unconditional.Length > 0) { sw.WriteLine(unconditional); } sw.WriteLine("\t\t\ttry {"); string call_setup = call.Setup("\t\t\t\t"); if (call_setup.Length > 0) { sw.WriteLine(call_setup); } if (retval.CSType == "void") { sw.WriteLine("\t\t\t\tmanaged ({0});", call); } else { sw.WriteLine("\t\t\t\t{0} __ret = managed ({1});", retval.CSType, call); } string finish = call.Finish("\t\t\t\t"); if (finish.Length > 0) { sw.WriteLine(finish); } sw.WriteLine("\t\t\t\tif (release_on_call)\n\t\t\t\t\tgch.Free ();"); if (retval.CSType != "void") { sw.WriteLine("\t\t\t\treturn {0};", retval.ToNative("__ret")); } /* If the function expects one or more "out" parameters(error parameters are excluded) or has a return value different from void and bool, exceptions * thrown in the managed function have to be considered fatal meaning that an exception is to be thrown and the function call cannot not return */ bool fatal = (retval.MarshalType != "void" && retval.MarshalType != "bool") || call.HasOutParam; sw.WriteLine("\t\t\t} catch (Exception e) {"); sw.WriteLine("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");"); if (fatal) { sw.WriteLine("\t\t\t\t// NOTREACHED: Above call does not return."); sw.WriteLine("\t\t\t\tthrow e;"); } else if (retval.MarshalType == "bool") { sw.WriteLine("\t\t\t\treturn false;"); } sw.WriteLine("\t\t\t}"); sw.WriteLine("\t\t}"); sw.WriteLine(); sw.WriteLine("\t\tbool release_on_call = false;"); sw.WriteLine("\t\tGCHandle gch;"); sw.WriteLine(); sw.WriteLine("\t\tpublic void PersistUntilCalled ()"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\trelease_on_call = true;"); sw.WriteLine("\t\t\tgch = GCHandle.Alloc (this);"); sw.WriteLine("\t\t}"); sw.WriteLine(); sw.WriteLine("\t\tinternal " + wrapper + " NativeDelegate;"); sw.WriteLine("\t\t" + NS + "." + Name + " managed;"); sw.WriteLine(); sw.WriteLine("\t\tpublic " + Name + "Wrapper (" + NS + "." + Name + " managed)"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\tthis.managed = managed;"); sw.WriteLine("\t\t\tif (managed != null)"); sw.WriteLine("\t\t\t\tNativeDelegate = new " + wrapper + " (NativeCallback);"); sw.WriteLine("\t\t}"); sw.WriteLine(); sw.WriteLine("\t\tpublic static " + NS + "." + Name + " GetManagedDelegate (" + wrapper + " native)"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\tif (native == null)"); sw.WriteLine("\t\t\t\treturn null;"); sw.WriteLine("\t\t\t" + Name + "Wrapper wrapper = (" + Name + "Wrapper) native.Target;"); sw.WriteLine("\t\t\tif (wrapper == null)"); sw.WriteLine("\t\t\t\treturn null;"); sw.WriteLine("\t\t\treturn wrapper.managed;"); sw.WriteLine("\t\t}"); sw.WriteLine("\t}"); sw.WriteLine("#endregion"); sw.WriteLine("}"); sw.Close(); gen_info.Writer = save_sw; return(NS + "Sharp." + Name + "Wrapper"); }
public void GenerateCallback (StreamWriter sw) { if (!Validate ()) return; ManagedCallString call = new ManagedCallString (parms, true); string type = parms [0].CSType + "Implementor"; string name = parms [0].Name; string call_string = "__obj." + Name + " (" + call + ")"; if (IsGetter) call_string = "__obj." + (Name.StartsWith ("Get") ? Name.Substring (3) : Name); else if (IsSetter) call_string = "__obj." + Name.Substring (3) + " = " + call; sw.WriteLine ("\t\t[GLib.CDeclCallback]"); sw.WriteLine ("\t\tdelegate " + MarshalReturnType + " " + Name + "Delegate (" + parms.ImportSignature + ");"); sw.WriteLine (); sw.WriteLine ("\t\tstatic " + MarshalReturnType + " " + Name + "Callback (" + parms.ImportSignature + ")"); sw.WriteLine ("\t\t{"); string unconditional = call.Unconditional ("\t\t\t"); if (unconditional.Length > 0) sw.WriteLine (unconditional); sw.WriteLine ("\t\t\ttry {"); sw.WriteLine ("\t\t\t\t" + type + " __obj = GLib.Object.GetObject (" + name + ", false) as " + type + ";"); sw.Write (call.Setup ("\t\t\t\t")); if (retval.IsVoid) { if (IsGetter) { Parameter p = parms [1]; string out_name = p.Name; if (p.MarshalType != p.CSType) out_name = "my" + out_name; sw.WriteLine ("\t\t\t\t" + out_name + " = " + call_string + ";"); } else sw.WriteLine ("\t\t\t\t" + call_string + ";"); } else sw.WriteLine ("\t\t\t\t" + retval.CSType + " __result = " + call_string + ";"); bool fatal = parms.HasOutParam || !retval.IsVoid; sw.Write (call.Finish ("\t\t\t\t")); if (!retval.IsVoid) sw.WriteLine ("\t\t\t\treturn " + retval.ToNative ("__result") + ";"); sw.WriteLine ("\t\t\t} catch (Exception e) {"); sw.WriteLine ("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");"); if (fatal) { sw.WriteLine ("\t\t\t\t// NOTREACHED: above call does not return."); sw.WriteLine ("\t\t\t\tthrow e;"); } sw.WriteLine ("\t\t\t}"); sw.WriteLine ("\t\t}"); }
public void GenerateCallback(StreamWriter sw) { if (!Validate()) { return; } ManagedCallString call = new ManagedCallString(parms, true); string type = parms [0].CSType + "Implementor"; string name = parms [0].Name; string call_string = "__obj." + Name + " (" + call + ")"; if (IsGetter) { call_string = "__obj." + (Name.StartsWith("Get") ? Name.Substring(3) : Name); } else if (IsSetter) { call_string = "__obj." + Name.Substring(3) + " = " + call; } sw.WriteLine("\t\t[GLib.CDeclCallback]"); sw.WriteLine("\t\tdelegate " + MarshalReturnType + " " + Name + "Delegate (" + parms.ImportSignature + ");"); sw.WriteLine(); sw.WriteLine("\t\tstatic " + MarshalReturnType + " " + Name + "Callback (" + parms.ImportSignature + ")"); sw.WriteLine("\t\t{"); string unconditional = call.Unconditional("\t\t\t"); if (unconditional.Length > 0) { sw.WriteLine(unconditional); } sw.WriteLine("\t\t\ttry {"); sw.WriteLine("\t\t\t\t" + type + " __obj = GLib.Object.GetObject (" + name + ", false) as " + type + ";"); sw.Write(call.Setup("\t\t\t\t")); if (retval.IsVoid) { if (IsGetter) { Parameter p = parms [1]; string out_name = p.Name; if (p.MarshalType != p.CSType) { out_name = "my" + out_name; } sw.WriteLine("\t\t\t\t" + out_name + " = " + call_string + ";"); } else { sw.WriteLine("\t\t\t\t" + call_string + ";"); } } else { sw.WriteLine("\t\t\t\t" + retval.CSType + " __result = " + call_string + ";"); } bool fatal = parms.HasOutParam || !retval.IsVoid; sw.Write(call.Finish("\t\t\t\t")); if (!retval.IsVoid) { sw.WriteLine("\t\t\t\treturn " + retval.ToNative("__result") + ";"); } sw.WriteLine("\t\t\t} catch (Exception e) {"); sw.WriteLine("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");"); if (fatal) { sw.WriteLine("\t\t\t\t// NOTREACHED: above call does not return."); sw.WriteLine("\t\t\t\tthrow e;"); } sw.WriteLine("\t\t\t}"); sw.WriteLine("\t\t}"); }
public string GenWrapper (GenerationInfo gen_info) { string wrapper = Name + "Native"; string qualname = MarshalType; if (!Validate ()) return String.Empty; body = new MethodBody (parms); StreamWriter save_sw = gen_info.Writer; StreamWriter sw = gen_info.Writer = gen_info.OpenStream (qualname, NS); sw.WriteLine ("namespace " + NS + "Sharp {"); sw.WriteLine (); sw.WriteLine ("\tusing System;"); sw.WriteLine ("\tusing System.Runtime.InteropServices;"); sw.WriteLine (); sw.WriteLine ("#region Autogenerated code"); sw.WriteLine ("\t[UnmanagedFunctionPointer (CallingConvention.Cdecl)]"); sw.WriteLine ("\tinternal delegate " + retval.MarshalType + " " + wrapper + "(" + parms.ImportSignature + ");"); sw.WriteLine (); GenInvoker (gen_info, sw); sw.WriteLine ("\tinternal class " + Name + "Wrapper {"); sw.WriteLine (); ManagedCallString call = new ManagedCallString (parms); sw.WriteLine ("\t\tpublic " + retval.MarshalType + " NativeCallback (" + parms.ImportSignature + ")"); sw.WriteLine ("\t\t{"); string unconditional = call.Unconditional ("\t\t\t"); if (unconditional.Length > 0) sw.WriteLine (unconditional); sw.WriteLine ("\t\t\ttry {"); string call_setup = call.Setup ("\t\t\t\t"); if (call_setup.Length > 0) sw.WriteLine (call_setup); if (retval.CSType == "void") sw.WriteLine ("\t\t\t\tmanaged ({0});", call); else sw.WriteLine ("\t\t\t\t{0} __ret = managed ({1});", retval.CSType, call); string finish = call.Finish ("\t\t\t\t"); if (finish.Length > 0) sw.WriteLine (finish); sw.WriteLine ("\t\t\t\tif (release_on_call)\n\t\t\t\t\tgch.Free ();"); Parameter cnt = retval.CountParameter; if (cnt != null) sw.WriteLine ("\t\t\t\t{0} = {1}{2};", cnt.Name, cnt.CSType == "int" ? String.Empty : "(" + cnt.MarshalType + ")(" + cnt.CSType + ")", "__ret.Length"); if (retval.CSType != "void") sw.WriteLine ("\t\t\t\treturn {0};", retval.ToNative ("__ret")); /* If the function expects one or more "out" parameters(error parameters are excluded) or has a return value different from void and bool, exceptions * thrown in the managed function have to be considered fatal meaning that an exception is to be thrown and the function call cannot not return */ bool fatal = (retval.MarshalType != "void" && retval.MarshalType != "bool") || call.HasOutParam; sw.WriteLine ("\t\t\t} catch (Exception e) {"); sw.WriteLine ("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");"); if (fatal) { sw.WriteLine ("\t\t\t\t// NOTREACHED: Above call does not return."); sw.WriteLine ("\t\t\t\tthrow e;"); } else if (retval.MarshalType == "bool") { sw.WriteLine ("\t\t\t\treturn false;"); } sw.WriteLine ("\t\t\t}"); sw.WriteLine ("\t\t}"); sw.WriteLine (); sw.WriteLine ("\t\tbool release_on_call = false;"); sw.WriteLine ("\t\tGCHandle gch;"); sw.WriteLine (); sw.WriteLine ("\t\tpublic void PersistUntilCalled ()"); sw.WriteLine ("\t\t{"); sw.WriteLine ("\t\t\trelease_on_call = true;"); sw.WriteLine ("\t\t\tgch = GCHandle.Alloc (this);"); sw.WriteLine ("\t\t}"); sw.WriteLine (); sw.WriteLine ("\t\tinternal " + wrapper + " NativeDelegate;"); sw.WriteLine ("\t\t" + NS + "." + Name + " managed;"); sw.WriteLine (); sw.WriteLine ("\t\tpublic " + Name + "Wrapper (" + NS + "." + Name + " managed)"); sw.WriteLine ("\t\t{"); sw.WriteLine ("\t\t\tthis.managed = managed;"); sw.WriteLine ("\t\t\tif (managed != null)"); sw.WriteLine ("\t\t\t\tNativeDelegate = new " + wrapper + " (NativeCallback);"); sw.WriteLine ("\t\t}"); sw.WriteLine (); sw.WriteLine ("\t\tpublic static " + NS + "." + Name + " GetManagedDelegate (" + wrapper + " native)"); sw.WriteLine ("\t\t{"); sw.WriteLine ("\t\t\tif (native == null)"); sw.WriteLine ("\t\t\t\treturn null;"); sw.WriteLine ("\t\t\t" + Name + "Wrapper wrapper = (" + Name + "Wrapper) native.Target;"); sw.WriteLine ("\t\t\tif (wrapper == null)"); sw.WriteLine ("\t\t\t\treturn null;"); sw.WriteLine ("\t\t\treturn wrapper.managed;"); sw.WriteLine ("\t\t}"); sw.WriteLine ("\t}"); sw.WriteLine ("#endregion"); sw.WriteLine ("}"); sw.Close (); gen_info.Writer = save_sw; return NS + "Sharp." + Name + "Wrapper"; }
private void GenDefaultHandlerDelegate(GenerationInfo gen_info, ClassBase implementor) { StreamWriter sw = gen_info.Writer; StreamWriter glue; bool use_glue = gen_info.GlueEnabled && implementor == null && ClassFieldName.Length > 0; string glue_name = String.Empty; ManagedCallString call = new ManagedCallString(parms, true); sw.WriteLine("\t\t[UnmanagedFunctionPointer (CallingConvention.Cdecl)]"); sw.WriteLine("\t\tdelegate " + retval.ToNativeType + " " + Name + "VMDelegate (" + parms.CallbackImportSignature + ");\n"); if (use_glue) { glue = gen_info.GlueWriter; glue_name = String.Format("{0}sharp_{1}_override_{2}", container_type.NS.ToLower().Replace(".", "_"), container_type.Name.ToLower(), ClassFieldName); sw.WriteLine("\t\t[DllImport (\"{0}\", CallingConvention = CallingConvention.Cdecl)]", gen_info.GluelibName); sw.WriteLine("\t\tstatic extern void {0} (IntPtr gtype, {1}VMDelegate cb);\n", glue_name, Name); glue.WriteLine("void {0} (GType gtype, gpointer cb);\n", glue_name); glue.WriteLine("void\n{0} (GType gtype, gpointer cb)", glue_name); glue.WriteLine("{"); glue.WriteLine("\tGObjectClass *klass = g_type_class_peek (gtype);"); glue.WriteLine("\tif (klass == NULL)"); glue.WriteLine("\t\tklass = g_type_class_ref (gtype);"); glue.WriteLine("\t(({0} *)klass)->{1} = cb;", container_type.CName + "Class", ClassFieldName); glue.WriteLine("}\n"); } sw.WriteLine("\t\tstatic {0} {1};\n", Name + "VMDelegate", Name + "VMCallback"); sw.WriteLine("\t\tstatic " + retval.ToNativeType + " " + Name.ToLower() + "_cb (" + parms.CallbackImportSignature + ")"); sw.WriteLine("\t\t{"); string unconditional = call.Unconditional("\t\t\t"); if (unconditional.Length > 0) { sw.WriteLine(unconditional); } sw.WriteLine("\t\t\ttry {"); sw.WriteLine("\t\t\t\t{0} {1}_managed = GLib.Object.GetObject ({1}, false) as {0};", implementor != null ? implementor.Name : container_type.Name, parms[0].Name); sw.Write(call.Setup("\t\t\t\t")); sw.Write("\t\t\t\t{0}", IsVoid ? "" : retval.CSType == retval.ToNativeType ? "return " : retval.CSType + " raw_ret = "); sw.WriteLine("{2}_managed.{0} ({1});", "On" + Name, call.ToString(), parms[0].Name); sw.Write(call.Finish("\t\t\t\t")); if (!IsVoid && retval.CSType != retval.ToNativeType) { sw.WriteLine("\t\t\t\treturn {0};", SymbolTable.Table.ToNativeReturn(retval.CType, "raw_ret")); } sw.WriteLine("\t\t\t} catch (Exception e) {"); bool fatal = HasOutParams || !IsVoid; sw.WriteLine("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");"); if (fatal) { sw.WriteLine("\t\t\t\t// NOTREACHED: above call doesn't return"); sw.WriteLine("\t\t\t\tthrow e;"); } sw.WriteLine("\t\t\t}"); sw.WriteLine("\t\t}\n"); sw.WriteLine("\t\tprivate static void Override" + Name + " (GLib.GType gtype)"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\tif (" + Name + "VMCallback == null)"); sw.WriteLine("\t\t\t\t" + Name + "VMCallback = new " + Name + "VMDelegate (" + Name.ToLower() + "_cb);"); if (use_glue) { sw.WriteLine("\t\t\t{0} (gtype.Val, {1}VMCallback);", glue_name, Name); } else { sw.WriteLine("\t\t\tOverrideVirtualMethod (gtype, " + CName + ", " + Name + "VMCallback);"); } sw.WriteLine("\t\t}\n"); }
private void GenDefaultHandlerDelegate (GenerationInfo gen_info, ClassBase implementor) { StreamWriter sw = gen_info.Writer; StreamWriter glue; bool use_glue = gen_info.GlueEnabled && implementor == null && ClassFieldName.Length > 0; string glue_name = String.Empty; ManagedCallString call = new ManagedCallString (parms, true); sw.WriteLine ("\t\t[GLib.CDeclCallback]"); sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + Name + "VMDelegate (" + parms.ImportSignature + ");\n"); if (use_glue) { glue = gen_info.GlueWriter; glue_name = String.Format ("{0}sharp_{1}_override_{2}", container_type.NS.ToLower ().Replace (".", "_"), container_type.Name.ToLower (), ClassFieldName); sw.WriteLine ("\t\t[DllImport (\"{0}\")]", gen_info.GluelibName); sw.WriteLine ("\t\tstatic extern void {0} (IntPtr gtype, {1}VMDelegate cb);\n", glue_name, Name); glue.WriteLine ("void {0} (GType gtype, gpointer cb);\n", glue_name); glue.WriteLine ("void\n{0} (GType gtype, gpointer cb)", glue_name); glue.WriteLine ("{"); glue.WriteLine ("\tGObjectClass *klass = g_type_class_peek (gtype);"); glue.WriteLine ("\tif (klass == NULL)"); glue.WriteLine ("\t\tklass = g_type_class_ref (gtype);"); glue.WriteLine ("\t(({0} *)klass)->{1} = cb;", container_type.CName + "Class", ClassFieldName); glue.WriteLine ("}\n"); } sw.WriteLine ("\t\tstatic {0} {1};\n", Name + "VMDelegate", Name + "VMCallback"); sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + Name.ToLower() + "_cb (" + parms.ImportSignature + ")"); sw.WriteLine ("\t\t{"); string unconditional = call.Unconditional ("\t\t\t"); if (unconditional.Length > 0) sw.WriteLine (unconditional); sw.WriteLine ("\t\t\ttry {"); sw.WriteLine ("\t\t\t\t{0} {1}_managed = GLib.Object.GetObject ({1}, false) as {0};", implementor != null ? implementor.Name : container_type.Name, parms[0].Name); sw.Write (call.Setup ("\t\t\t\t")); sw.Write ("\t\t\t\t{0}", IsVoid ? "" : retval.CSType == retval.ToNativeType ? "return " : retval.CSType + " raw_ret = "); sw.WriteLine ("{2}_managed.{0} ({1});", "On" + Name, call.ToString (), parms[0].Name); sw.Write (call.Finish ("\t\t\t\t")); if (!IsVoid && retval.CSType != retval.ToNativeType) sw.WriteLine ("\t\t\t\treturn {0};", SymbolTable.Table.ToNativeReturn (retval.CType, "raw_ret")); sw.WriteLine ("\t\t\t} catch (Exception e) {"); bool fatal = HasOutParams || !IsVoid; sw.WriteLine ("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");"); if (fatal) { sw.WriteLine ("\t\t\t\t// NOTREACHED: above call doesn't return"); sw.WriteLine ("\t\t\t\tthrow e;"); } sw.WriteLine ("\t\t\t}"); sw.WriteLine ("\t\t}\n"); sw.WriteLine ("\t\tprivate static void Override" + Name + " (GLib.GType gtype)"); sw.WriteLine ("\t\t{"); sw.WriteLine ("\t\t\tif (" + Name + "VMCallback == null)"); sw.WriteLine ("\t\t\t\t" + Name + "VMCallback = new " + Name + "VMDelegate (" + Name.ToLower() + "_cb);"); if (use_glue) sw.WriteLine ("\t\t\t{0} (gtype.Val, {1}VMCallback);", glue_name, Name); else sw.WriteLine ("\t\t\tOverrideVirtualMethod (gtype, " + CName + ", " + Name + "VMCallback);"); sw.WriteLine ("\t\t}\n"); }