public void GenArgsCleanup(StreamWriter sw, string finish) { if (retval.IsVoid && finish.Length == 0) { return; } sw.WriteLine("\n\t\t\ttry {"); sw.Write(finish); if (!retval.IsVoid) { if (retval.CSType == "bool") { sw.WriteLine("\t\t\t\tif (args.RetVal == null)"); sw.WriteLine("\t\t\t\t\treturn false;"); } sw.WriteLine("\t\t\t\treturn {0};", retval.ToNative(String.Format("(({0}) args.RetVal)", retval.CSType))); } sw.WriteLine("\t\t\t} catch (Exception) {"); sw.WriteLine("\t\t\t\tException ex = new Exception (\"args.RetVal or 'out' property unset or set to incorrect type in " + EventHandlerQualifiedName + " callback\");"); sw.WriteLine("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (ex, true);"); sw.WriteLine("\t\t\t\t// NOTREACHED: above call doesn't return."); sw.WriteLine("\t\t\t\tthrow ex;"); sw.WriteLine("\t\t\t}"); }
/* 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}"); }