diff --git a/ChangeLog b/ChangeLog index bfffcc9b6..f18b626be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-06-17 Mike Kestner + + * glib/SignalClosure.cs: post back the gvalues after the closure is + invoked using a new Update method on GLib.Value. This only impacts + boxed types, since they are the only "value types" passed by ref in + the signal marshaling environment. We can't call set_boxed on the + value to update it, since that allocs new memory, we need to marshal + the updated struct out to the existing native memory address using + g_value_get_boxed. + * glib/Value.cs (Update): new update method for writing values to + an existing boxed type instance instead of allocating a new native + struct. Fixes #398929. + 2008-06-17 Mike Kestner * glib/GType.cs (LookupType): traversed referenced assemblies to diff --git a/glib/SignalClosure.cs b/glib/SignalClosure.cs index c5738f271..82bed1aa2 100644 --- a/glib/SignalClosure.cs +++ b/glib/SignalClosure.cs @@ -134,13 +134,19 @@ namespace GLib { SignalArgs args = Activator.CreateInstance (closure.args_type, new object [0]) as SignalArgs; args.Args = new object [n_param_vals - 1]; + GLib.Value[] vals = new GLib.Value [n_param_vals - 1]; for (int i = 1; i < n_param_vals; i++) { IntPtr ptr = new IntPtr (param_values.ToInt64 () + i * Marshal.SizeOf (typeof (Value))); - Value val = (Value) Marshal.PtrToStructure (ptr, typeof (Value)); - args.Args [i - 1] = val.Val; + vals [i - 1] = (Value) Marshal.PtrToStructure (ptr, typeof (Value)); + args.Args [i - 1] = vals [i - 1].Val; } ClosureInvokedArgs ci_args = new ClosureInvokedArgs (__obj, args); closure.Invoke (ci_args); + for (int i = 1; i < n_param_vals; i++) { + vals [i - 1].Update (args.Args [i - 1]); + IntPtr ptr = new IntPtr (param_values.ToInt64 () + i * Marshal.SizeOf (typeof (Value))); + Marshal.StructureToPtr (vals [i - 1], ptr, false); + } if (return_val == IntPtr.Zero || args.RetVal == null) return; diff --git a/glib/Value.cs b/glib/Value.cs index d98374210..5190afe2c 100755 --- a/glib/Value.cs +++ b/glib/Value.cs @@ -411,6 +411,12 @@ namespace GLib { } } + internal void Update (object val) + { + if (g_type_is_a (type, GType.Boxed.Val) && !(val is IWrapper)) + Marshal.StructureToPtr (val, g_value_get_boxed (ref this), false); + } + [DllImport("libgobject-2.0-0.dll")] static extern void g_value_init (ref GLib.Value val, IntPtr gtype);