diff --git a/ChangeLog b/ChangeLog index 088ac8f67..7dad5d501 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-06-30 Dan Winship + + * generator/Parameters.cs (AllowComplexRefs): new property for + whether or not to allow "complex" ref/out args. + (Validate): update for that + + * generator/Signal.cs: set AllowComplexRefs false on the params. + (Validate): fix the messages + (GenCallback, GenEventHandler): properly handle ref/out args, by + manually pointerifying them (except for boxed args, which are + already pointers). + + * glib/Marshaller.cs (StructureToPtrAlloc): Rename from + PtrToStructureAlloc, since it wraps Marshal.StructureToPtr. + 2005-06-28 Mike Kestner * gtk/ComboBox.custom : add ctor (string[]). diff --git a/doc/en/GLib/Marshaller.xml b/doc/en/GLib/Marshaller.xml index d03fa6f9c..26407e12a 100644 --- a/doc/en/GLib/Marshaller.xml +++ b/doc/en/GLib/Marshaller.xml @@ -223,8 +223,8 @@ - - + + Method System.IntPtr @@ -233,10 +233,10 @@ - To be added - a - a - To be added + the structure to marshal + Marshals a structure to newly-allocated memory. + a pointer to the newly-allocated memory + This is like except that it allocates the memory for the unmanaged copy itself. You should free the memory with when you are done with it. diff --git a/generator/Parameters.cs b/generator/Parameters.cs index 6c6d4db99..a3e5c0103 100644 --- a/generator/Parameters.cs +++ b/generator/Parameters.cs @@ -310,6 +310,12 @@ namespace GtkSharp.Generation { set { is_static = value; } } + bool allow_complex_refs; + public bool AllowComplexRefs { + get { return allow_complex_refs; } + set { allow_complex_refs = value; } + } + bool cleared = false; void Clear () { @@ -344,6 +350,14 @@ namespace GtkSharp.Generation { return false; } + if (p.PassAs != "" && !allow_complex_refs) { + if (!(p.Generatable is BoxedGen) && + !(p.Generatable is SimpleGen)) { + Console.Write("Complex " + p.PassAs + " param " + p.Name + " "); + return false; + } + } + if (p.Generatable is CallbackGen) { has_cb = true; if (i == Count - 3 && diff --git a/generator/Signal.cs b/generator/Signal.cs index 0b3466fd8..b0bdee2c7 100644 --- a/generator/Signal.cs +++ b/generator/Signal.cs @@ -41,6 +41,7 @@ namespace GtkSharp.Generation { name = elem.GetAttribute ("name"); retval = new ReturnValue (elem ["return-type"]); parms = new Parameters (elem["parameters"]); + parms.AllowComplexRefs = false; this.container_type = container_type; } @@ -56,16 +57,16 @@ namespace GtkSharp.Generation { public bool Validate () { if (Name == "") { - Console.Write ("bad signal " + Name); + Console.Write ("Nameless signal "); Statistics.ThrottledCount++; return false; } - if (!parms.Validate ()) - return false; - - if (!retval.Validate ()) + if (!parms.Validate () || !retval.Validate ()) { + Console.Write (" in signal " + Name + " "); + Statistics.ThrottledCount++; return false; + } return true; } @@ -208,16 +209,18 @@ namespace GtkSharp.Generation { for (int idx = 1; idx < parms.Count; idx++) { Parameter p = parms [idx]; IGeneratable igen = p.Generatable; - if (p.PassAs == "out") + if (p.PassAs != "out") { + if (igen is ManualGen) { + sw.WriteLine("\t\t\tif (arg{0} == IntPtr.Zero)", idx); + sw.WriteLine("\t\t\t\targs.Args[{0}] = null;", idx - 1); + sw.WriteLine("\t\t\telse {"); + sw.WriteLine("\t\t\t\targs.Args[" + (idx - 1) + "] = " + igen.FromNative ("arg" + idx) + ";"); + sw.WriteLine("\t\t\t}"); + } else + sw.WriteLine("\t\t\targs.Args[" + (idx - 1) + "] = " + igen.FromNative ("arg" + idx) + ";"); + } + if (p.PassAs != "") finish += "\t\t\targ" + idx + " = " + igen.ToNativeReturn ("((" + p.CSType + ")args.Args[" + (idx - 1) + "])") + ";\n"; - else if (igen is ManualGen) { - sw.WriteLine("\t\t\tif (arg{0} == IntPtr.Zero)", idx); - sw.WriteLine("\t\t\t\targs.Args[{0}] = null;", idx - 1); - sw.WriteLine("\t\t\telse {"); - sw.WriteLine("\t\t\t\targs.Args[" + (idx - 1) + "] = " + igen.FromNative ("arg" + idx) + ";"); - sw.WriteLine("\t\t\t}"); - } else - sw.WriteLine("\t\t\targs.Args[" + (idx - 1) + "] = " + igen.FromNative ("arg" + idx) + ";"); } sw.WriteLine("\t\t\t{0} handler = ({0}) sig.Handler;", EventHandlerQualifiedName); sw.WriteLine("\t\t\thandler (GLib.Object.GetObject (arg0), args);"); @@ -299,13 +302,28 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\t\tinst_and_params.Append (vals [0]);"); string cleanup = ""; for (int i = 1; i < parms.Count; i++) { - if (parms [i].PassAs == "out") { - sw.WriteLine ("\t\t\tvals [" + i + "] = GLib.Value.Empty;"); - cleanup += "\t\t\t" + parms [i].Name + " = (" + parms [i].CSType + ") vals [" + i + "];\n"; - } else if (parms [i].IsLength && parms [i - 1].IsString) + Parameter p = parms [i]; + if (p.PassAs != "") { + if (SymbolTable.Table.IsBoxed (p.CType)) { + if (p.PassAs == "ref") + sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value (" + p.Name + ");"); + else + sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value ((GLib.GType)typeof (" + p.CSType + "));"); + cleanup += "\t\t\t" + p.Name + " = (" + p.CSType + ") vals [" + i + "];\n"; + } else { + if (p.PassAs == "ref") + sw.WriteLine ("\t\t\tIntPtr " + p.Name + "_ptr = GLib.Marshaller.StructureToPtrAlloc ((" + p.CSType + ") " + p.Name + ");"); + else + sw.WriteLine ("\t\t\tIntPtr " + p.Name + "_ptr = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (" + p.CSType + ")));"); + + sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value (" + p.Name + "_ptr);"); + cleanup += "\t\t\t" + p.Name + " = (" + p.CSType + ") Marshal.PtrToStructure (" + p.Name + "_ptr, typeof (" + p.CSType + "));\n"; + cleanup += "\t\t\tMarshal.FreeHGlobal (" + p.Name + "_ptr);\n"; + } + } else if (p.IsLength && parms [i - 1].IsString) sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value (" + parms [i-1].Name + ".Length);"); else - sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value (" + parms [i].Name + ");"); + sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value (" + p.Name + ");"); sw.WriteLine ("\t\t\tinst_and_params.Append (vals [" + i + "]);"); } diff --git a/glib/Marshaller.cs b/glib/Marshaller.cs index d7b8615d5..1a995e122 100644 --- a/glib/Marshaller.cs +++ b/glib/Marshaller.cs @@ -274,7 +274,7 @@ namespace GLib { return glibsharp_utf16_to_unichar ((ushort) c); } - public static IntPtr PtrToStructureAlloc (object o) + public static IntPtr StructureToPtrAlloc (object o) { IntPtr result = Marshal.AllocHGlobal (Marshal.SizeOf (o)); Marshal.StructureToPtr (o, result, false);