From e38ece1fdb20be00caa85b87837cd1d6e202451c Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Tue, 21 Dec 2004 19:47:55 +0000 Subject: [PATCH] 2004-12-21 Mike Kestner * glib/Argv.cs : argv marshaling class. * glib/Makefile.am : add file. * glib/Marshaller.cs : mark the argv methods obsolete. * gtk/Application.cs : use GLib.Argv. [Fixes #68812] svn path=/trunk/gtk-sharp/; revision=38046 --- ChangeLog | 7 ++++ doc/en/GLib/Argv.xml | 77 ++++++++++++++++++++++++++++++++++++++++++ glib/Argv.cs | 79 ++++++++++++++++++++++++++++++++++++++++++++ glib/Makefile.am | 1 + glib/Marshaller.cs | 2 ++ gtk/Application.cs | 10 ++++-- 6 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 doc/en/GLib/Argv.xml create mode 100644 glib/Argv.cs diff --git a/ChangeLog b/ChangeLog index 78058f415..8068a75ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-12-21 Mike Kestner + + * glib/Argv.cs : argv marshaling class. + * glib/Makefile.am : add file. + * glib/Marshaller.cs : mark the argv methods obsolete. + * gtk/Application.cs : use GLib.Argv. [Fixes #68812] + 2004-12-21 Dan Winship * generator/CallbackGen.cs: diff --git a/doc/en/GLib/Argv.xml b/doc/en/GLib/Argv.xml new file mode 100644 index 000000000..9e479914b --- /dev/null +++ b/doc/en/GLib/Argv.xml @@ -0,0 +1,77 @@ + + + + glib-sharp + [00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00 71 EB 6C 55 75 52 9C BF 72 44 F7 A6 EA 05 62 84 F9 EA E0 3B CF F2 CC 13 2C 9C 49 0A B3 09 EA B0 B5 6B CE 44 9D F5 03 D9 C0 A8 1E 52 05 85 CD BE 70 E2 FB 90 43 4B AC 04 FA 62 22 A8 00 98 B7 A1 A7 B3 AF 99 1A 41 23 24 BB 43 25 F6 B8 65 BB 64 EB F6 D1 C2 06 D5 73 2D DF BC 70 A7 38 9E E5 3E 0C 24 6E 32 79 74 1A D0 05 03 E4 98 42 E1 9B F3 7B 19 8B 40 21 26 CB 36 89 C2 EA 64 96 A4 7C B4] + 2.0.0.0 + neutral + + + Gtk# is thread aware, but not thread safe; See the Gtk# Thread Programming for details. + + Argv marshaling class. + + + + System.Object + + + + + + + Method + + System.Void + + + + Releases native resources. + + + + + + Method + + System.String[] + + + + + + Gets a string array containing a specified number of arguments. + a + a + + + + + + Constructor + + + + + + Creates an Argv marshaler. + a + a + + + + + + Property + + System.IntPtr + + + + Native pointer to the argument array. + a + + + + + diff --git a/glib/Argv.cs b/glib/Argv.cs new file mode 100644 index 000000000..66ca99b79 --- /dev/null +++ b/glib/Argv.cs @@ -0,0 +1,79 @@ +// GLib.Argv.cs : Argv marshaling class +// +// Author: Mike Kestner +// +// Copyright (c) 2004 Novell, Inc. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the Lesser GNU General +// Public License as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + + +namespace GLib { + + using System; + using System.Runtime.InteropServices; + + public class Argv { + + IntPtr[] arg_ptrs; + IntPtr handle; + + [DllImport("libglib-2.0-0.dll")] + static extern IntPtr g_strdup (string str); + + [DllImport("libglib-2.0-0.dll")] + static extern IntPtr g_malloc(IntPtr size); + + [DllImport("libglib-2.0-0.dll")] + static extern void g_free (IntPtr mem); + + ~Argv () + { + foreach (IntPtr arg in arg_ptrs) + g_free (arg); + + g_free (handle); + } + + public Argv (string[] args) + { + arg_ptrs = new IntPtr [args.Length]; + + for (int i = 0; i < args.Length; i++) + arg_ptrs [i] = g_strdup (args[i]); + + handle = g_malloc (new IntPtr (IntPtr.Size * args.Length)); + + for (int i = 0; i < args.Length; i++) + Marshal.WriteIntPtr (handle, i * IntPtr.Size, arg_ptrs [i]); + } + + public IntPtr Handle { + get { + return handle; + } + } + + public string[] GetArgs (int argc) + { + string[] result = new string [argc]; + + for (int i = 0; i < argc; i++) + result [i] = Marshal.PtrToStringAnsi (Marshal.ReadIntPtr (handle, i * IntPtr.Size)); + + return result; + } + } +} + diff --git a/glib/Makefile.am b/glib/Makefile.am index 45c04f9a3..ff59316c8 100644 --- a/glib/Makefile.am +++ b/glib/Makefile.am @@ -10,6 +10,7 @@ DISTCLEANFILES = $(ASSEMBLY).config AssemblyInfo.cs references = sources = \ + Argv.cs \ Boxed.cs \ ConnectBeforeAttribute.cs \ DefaultSignalHandlerAttribute.cs \ diff --git a/glib/Marshaller.cs b/glib/Marshaller.cs index 16210ca9c..7d1b7e4e5 100644 --- a/glib/Marshaller.cs +++ b/glib/Marshaller.cs @@ -109,6 +109,7 @@ namespace GLib { return buf; } + [Obsolete ("Use GLib.Argv instead to avoid leaks.")] public static IntPtr ArgvToArrayPtr (string[] args) { if (args.Length == 0) @@ -149,6 +150,7 @@ namespace GLib { return args; } + [Obsolete ("Use GLib.Argv instead to avoid leaks.")] public static string[] ArrayPtrToArgv (IntPtr array, int argc) { if (argc == 0) diff --git a/gtk/Application.cs b/gtk/Application.cs index ac4251386..d911e64d5 100755 --- a/gtk/Application.cs +++ b/gtk/Application.cs @@ -55,7 +55,8 @@ namespace Gtk { progargs[0] = progname; args.CopyTo (progargs, 1); - IntPtr buf = GLib.Marshaller.ArgvToArrayPtr (progargs); + GLib.Argv argv = new GLib.Argv (progargs); + IntPtr buf = argv.Handle; int argc = progargs.Length; if (check) @@ -63,13 +64,16 @@ namespace Gtk { else gtk_init (ref argc, ref buf); + if (buf != argv.Handle) + throw new Exception ("init returned new argv handle"); + // copy back the resulting argv, minus argv[0], which we're // not interested in. - if (argc == 0) + if (argc <= 1) args = new string[0]; else { - progargs = GLib.Marshaller.ArrayPtrToArgv (buf, argc); + progargs = argv.GetArgs (argc); args = new string[argc - 1]; Array.Copy (progargs, 1, args, 0, argc - 1); }