[Mono-list] Marshaling bug?

Pablo Baena pbaena@uol.com.ar
Sun, 26 Oct 2003 00:00:05 +0000


On Saturday 25 October 2003 17:23, you wrote:
> I don't think the problem is retrieving the value from g_list_nth_data.
> This is simple to check -- compare the value returned from
> g_list_nth_data against the value you put into the g_list.

That was because the data pointer was keeping the value of the previous 
allocation. This new sample code shows that both the first call to 
g_utf16_to_utf8 and memmove work OK, but either g_list_append or 
g_list_nth_data aren't working.
This is unless I'm doing something stupid.


------------------------------------------------------------------------------
using System;
using System.Runtime.InteropServices;

class testbug {

public const string GLIB_LIBRARY        = "glib-2.0";
public const string STRLEN_LIBRARY      = "pango-1.0";
public const string MEMMOVE_LIBRARY     = "gtk-x11-2.0";

[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)]
public static extern IntPtr g_utf16_to_utf8(char[] str, int len, out int 
items_read, out int items_written, IntPtr error);
[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)]
public static extern IntPtr g_utf8_to_utf16(byte[] str, int len, out int 
items_read, out int items_written, IntPtr error);

[DllImport(STRLEN_LIBRARY, CharSet = CharSet.Unicode)]
public static extern int strlen(IntPtr str);

[DllImport(MEMMOVE_LIBRARY, CharSet = CharSet.Unicode)]
public static extern void memmove(IntPtr dest, byte[] src, int size);
[DllImport(MEMMOVE_LIBRARY, CharSet = CharSet.Unicode)]
public static extern void memmove([In, Out] byte[] dest, IntPtr src, int 
size);
[DllImport(MEMMOVE_LIBRARY, CharSet = CharSet.Unicode)]
public static extern void memmove([In, Out] char[] dest, IntPtr src, int 
size);

[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)]
public static extern void g_free(IntPtr mem);
[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)]
public static extern IntPtr g_malloc(int size);

[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)]
static extern void g_printf (IntPtr format);

[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)]
public static extern IntPtr g_list_append(IntPtr list, IntPtr data);
[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)]
public static extern IntPtr g_list_nth_data(IntPtr list, int n);

public static void Main ()
{
	string str = "Let's i18n, baby...do it hard!";
	IntPtr glist = IntPtr.Zero;
	bool terminate = true;
	char [] strchar = str.ToCharArray();

	int read, written;
	IntPtr ptr = g_utf16_to_utf8 (strchar, str.Length, out read, out written, 
IntPtr.Zero);

	if (read != strchar.Length) written++;
	byte [] buffer = new byte [written + (terminate ? 1 : 0)];
	memmove (buffer, ptr, written);
	g_free (ptr);

	string newl = "\n";
	IntPtr data = g_malloc (buffer.Length);
	memmove (data, buffer, buffer.Length);
	g_printf (data);
	g_printf (Marshal.StringToHGlobalAnsi (newl));

	glist = g_list_append (glist, data);
	g_free (data);

	IntPtr data2 = g_list_nth_data (glist, 0);
	g_printf (data2);
	g_printf (Marshal.StringToHGlobalAnsi (newl));
	int length = strlen (data2);

	byte [] buffer1 = new byte [length];
	memmove (buffer1, data2, length);

	ptr = g_utf8_to_utf16 (buffer1, buffer1.Length, out read, out written, 
IntPtr.Zero);

	char [] chars = new char [written];
	memmove (chars, ptr, written * 2);

	Console.WriteLine (chars);

	g_free (ptr);
}

}
------------------------------------------------------------------------------------------------------------