From 793802f7be8d5546ab4990adc809aba35ac35836 Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Tue, 17 Jun 2008 20:18:23 +0000 Subject: [PATCH] 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. svn path=/trunk/gtk-sharp/; revision=106058 --- ChangeLog | 13 +++++++++++++ glib/SignalClosure.cs | 10 ++++++++-- glib/Value.cs | 6 ++++++ 3 files changed, 27 insertions(+), 2 deletions(-) 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);