[Mono-list] Marshaling bug?

pbaena@uol.com.ar pbaena@uol.com.ar
Sat, 25 Oct 2003 10:52:09 -0300 (GMT)


I reported a bug (#50116) about this problem of mine (of SWT really), and I wanted to get help from the experts to see if the API can be improved.

SWT works this way to append and retrieve from a g_list:

--------------------------------CODE-------------------------
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 int g_utf16_to_utf8(char[] str, int len, int[]
items_read, int[] items_written, int[] error);
[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)]
public static extern int g_utf8_to_utf16(byte[] str, int len, int[]
items_read, int[] items_written, int[] error);

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

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

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

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

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

        int [] items_read = new int [1], items_written = new int [1];
        int ptr = g_utf16_to_utf8 (strchar, str.Length, items_read, 
items_written, null);
 
        int written = items_written [0];
        //TEMPORARY CODE - convertion stops at the first NULL 
        if (items_read [0] != strchar.Length) written++;
        byte [] buffer = new byte [written + (terminate ? 1 : 0)]; 
        memmove (buffer, ptr, written);
        g_free (ptr); 

        int data = g_malloc (buffer.Length);
        memmove (data, buffer, buffer.Length); 
        glist = g_list_append (glist, data);
 
        data = g_list_nth_data (glist, 0);
        int length = strlen (data); 
        byte [] buffer1 = new byte [length];
        memmove (buffer1, data, length); 

        ptr = g_utf8_to_utf16 (buffer1, buffer1.Length, null,
items_written, null); 

        length = items_written [0]; 
        char [] chars = new char [length];
        memmove (chars, ptr, length * 2); 

        Console.WriteLine (chars); 

        g_free (ptr); 
}

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

That worked till mono 0.28, but doesn't work with current mono from CVS. Now I was testing things and found that this other approach to the problem works:

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

class testbug {

public const string GLIB_LIBRARY        = "glib-2.0";

[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)] 
public static extern int g_list_append(int list, IntPtr data);
[DllImport(GLIB_LIBRARY, CharSet = CharSet.Unicode)] 
public static extern string g_list_nth_data(int list, int n);
 
public static void Main ()
{ 
        string str = "Let's i18n, baby...do it hard!";
        int glist = 0; 

	glist = g_list_append (glist, Marshal.StringToHGlobalAnsi (str)); 
        string data2 = g_list_nth_data (glist, 0); 
	Console.WriteLine (data2);

	return;
}

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

Now I was wondering what are the advantages of the latest approach in contrast with SWT's. Can you give me some advice?

Thank you very much!
Pablo