From be28ed359769acd930229b6f94c15d8391d36a9c Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Fri, 29 Feb 2008 23:42:27 +0000 Subject: [PATCH] 2008-02-29 Mike Kestner * generator/ReturnValue.cs: null-term array handling. * glib/Marshaller.cs: marshaling methods for null-term arrays. svn path=/trunk/gtk-sharp/; revision=97032 --- ChangeLog | 5 +++ doc/en/GLib/Marshaller.xml | 49 ++++++++++++++++++++++++++ generator/ReturnValue.cs | 71 +++++++++++++++++--------------------- glib/Marshaller.cs | 32 +++++++++++++++++ 4 files changed, 117 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 614250e01..bed6798e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-02-29 Mike Kestner + + * generator/ReturnValue.cs: null-term array handling. + * glib/Marshaller.cs: marshaling methods for null-term arrays. + 2008-02-29 Mike Kestner * sample/Action.cs: qualify Action usage. diff --git a/doc/en/GLib/Marshaller.xml b/doc/en/GLib/Marshaller.xml index a3bfe30ed..e9f976501 100644 --- a/doc/en/GLib/Marshaller.xml +++ b/doc/en/GLib/Marshaller.xml @@ -373,5 +373,54 @@ + + + Method + + System.IntPtr + + + + + + Size in bytes to be allocated. + Allocates a block of heap memory using the glib allocator. + A pointer to the block. + + + + + + Method + + System.String[] + + + + + + + Pointer to a null-terminated string array. + Indicates if the memory is owned and should be released. + Marshals a native null-terminated string array to a managed string array. + an array of managed strings. + + + + + + Method + + System.Void + + + + + + Pointer to a native null-terminated string array. + Frees a string array, including its member strings. + + + diff --git a/generator/ReturnValue.cs b/generator/ReturnValue.cs index 8b06cfebb..d6548cbda 100644 --- a/generator/ReturnValue.cs +++ b/generator/ReturnValue.cs @@ -28,15 +28,29 @@ namespace GtkSharp.Generation { private XmlElement elem; + bool is_null_term; + bool is_array; + bool elements_owned; + bool owned; + string ctype = String.Empty; + string element_ctype = String.Empty; public ReturnValue (XmlElement elem) { this.elem = elem; + if (elem != null) { + is_null_term = elem.HasAttribute ("null_term_array"); + is_array = elem.HasAttribute ("array"); + elements_owned = elem.GetAttribute ("elements_owned") == "true"; + owned = elem.GetAttribute ("owned") == "true"; + ctype = elem.GetAttribute("type"); + element_ctype = elem.GetAttribute ("element_type"); + } } public string CType { get { - return elem == null ? String.Empty : elem.GetAttribute("type"); + return ctype; } } @@ -48,7 +62,7 @@ namespace GtkSharp.Generation { if (ElementType != String.Empty) return ElementType + "[]"; - return IGen.QualifiedName + (IsArray ? "[]" : String.Empty); + return IGen.QualifiedName + (is_array || is_null_term ? "[]" : String.Empty); } } @@ -60,28 +74,10 @@ namespace GtkSharp.Generation { } } - string ElementCType { - get { - if (elem != null && elem.HasAttribute ("element_type")) - return elem.GetAttribute ("element_type"); - - return String.Empty; - } - } - - bool ElementsOwned { - get { - if (elem != null && elem.GetAttribute ("elements_owned") == "true") - return true; - - return false; - } - } - string ElementType { get { - if (ElementCType.Length > 0) - return SymbolTable.Table.GetCSType (ElementCType); + if (element_ctype.Length > 0) + return SymbolTable.Table.GetCSType (element_ctype); return String.Empty; } @@ -96,12 +92,6 @@ namespace GtkSharp.Generation { } } - bool IsArray { - get { - return elem == null ? false : elem.HasAttribute ("array"); - } - } - public bool IsVoid { get { return CSType == "void"; @@ -112,13 +102,9 @@ namespace GtkSharp.Generation { get { if (IGen == null) return String.Empty; - return IGen.MarshalReturnType + (IsArray ? "[]" : String.Empty); - } - } - - bool Owned { - get { - return elem.GetAttribute ("owned") == "true"; + else if (is_null_term) + return "IntPtr"; + return IGen.MarshalReturnType + (is_array ? "[]" : String.Empty); } } @@ -126,7 +112,9 @@ namespace GtkSharp.Generation { get { if (IGen == null) return String.Empty; - return IGen.ToNativeReturnType + (IsArray ? "[]" : String.Empty); + else if (is_null_term) + return "IntPtr"; //FIXME + return IGen.ToNativeReturnType + (is_array ? "[]" : String.Empty); } } @@ -137,10 +125,12 @@ namespace GtkSharp.Generation { if (ElementType != String.Empty) { string type_str = "typeof (" + ElementType + ")"; - string args = type_str + ", " + (Owned ? "true" : "false") + ", " + (ElementsOwned ? "true" : "false"); + string args = type_str + ", " + (owned ? "true" : "false") + ", " + (elements_owned ? "true" : "false"); return String.Format ("({0}[]) GLib.Marshaller.ListToArray ({1}, {2})", ElementType, IGen.FromNativeReturn (var + ", " + args), type_str); } else if (IGen is HandleBase) - return ((HandleBase)IGen).FromNative (var, Owned); + return ((HandleBase)IGen).FromNative (var, owned); + else if (is_null_term) + return String.Format ("GLib.Marshaller.NullTermPtrToStringArray ({0}, {1})", var, owned ? "true" : "false"); else return IGen.FromNativeReturn (var); } @@ -151,9 +141,10 @@ namespace GtkSharp.Generation { return String.Empty; if (ElementType.Length > 0) { - string args = ", typeof (" + ElementType + "), " + (Owned ? "true" : "false") + ", " + (ElementsOwned ? "true" : "false"); + string args = ", typeof (" + ElementType + "), " + (owned ? "true" : "false") + ", " + (elements_owned ? "true" : "false"); var = "new " + IGen.QualifiedName + "(" + var + args + ")"; - } + } else if (is_null_term) + return String.Format ("GLib.Marshaller.StringArrayToNullTermPtr ({0})", var); if (IGen is IManualMarshaler) return (IGen as IManualMarshaler).AllocNative (var); diff --git a/glib/Marshaller.cs b/glib/Marshaller.cs index c99157249..9815744e8 100644 --- a/glib/Marshaller.cs +++ b/glib/Marshaller.cs @@ -150,6 +150,33 @@ namespace GLib { return result; } + [DllImport("libglib-2.0-0.dll")] + static extern void g_strfreev (IntPtr mem); + + public static void StrFreeV (IntPtr null_term_array) + { + g_strfreev (null_term_array); + } + + public static string[] NullTermPtrToStringArray (IntPtr null_term_array, bool owned) + { + if (null_term_array == IntPtr.Zero) + return new string [0]; + + int count = 0; + System.Collections.ArrayList result = new System.Collections.ArrayList (); + IntPtr s = Marshal.ReadIntPtr (null_term_array, count++ * IntPtr.Size); + while (s != IntPtr.Zero) { + result.Add (Utf8PtrToString (s)); + s = Marshal.ReadIntPtr (null_term_array, count++ * IntPtr.Size); + } + + if (owned) + g_strfreev (null_term_array); + + return (string[]) result.ToArray (typeof(string)); + } + public static string[] PtrToStringArrayGFree (IntPtr string_array) { if (string_array == IntPtr.Zero) @@ -180,6 +207,11 @@ namespace GLib { [DllImport("libglib-2.0-0.dll")] static extern IntPtr g_malloc(UIntPtr size); + public static IntPtr Malloc (ulong size) + { + return g_malloc (new UIntPtr (size)); + } + static bool check_sixtyfour () { int szint = Marshal.SizeOf (typeof (int)); int szlong = Marshal.SizeOf (typeof (long));