2008-06-17 Mike Kestner <mkestner@novell.com>

* 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
This commit is contained in:
Mike Kestner 2008-06-17 20:18:23 +00:00
parent 179d4b214f
commit 793802f7be
3 changed files with 27 additions and 2 deletions

View File

@ -1,3 +1,16 @@
2008-06-17 Mike Kestner <mkestner@novell.com>
* 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 <mkestner@novell.com>
* glib/GType.cs (LookupType): traversed referenced assemblies to

View File

@ -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;

View File

@ -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);