GNOME Bugzilla – Bug 627736
Gtk.TreeIterCompareFunc: self is the first parameter instead of the last
Last modified: 2010-10-08 23:28:47 UTC
With a code like this: public class Test : GLib.Object { public init_list_store () { ... list_store.set_sort_func (0, on_sort); ... } private int on_sort (TreeModel model, TreeIter a, TreeIter b) { ... } } valac produce a C code like this: static gint test_on_sort (Test* self, GtkTreeModel* model, GtkTreeIter* a, GtkTreeIter* b) { ... } "self" must be the last parameter, according to the API: gint (*GtkTreeIterCompareFunc) (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data); A workaround is to declare "on_sort" static: private static int on_sort (TreeModel model, TreeIter a, TreeIter b) Tested with Vala 0.9.7.
Nope, test_on_sort is generated correctly. You missed that set_sort_func actually uses a wrapper in the C code, named for your case "_test_on_sort_gtk_tree_iter_compare_func". If, for some reason, that doesn't happen, please attach a full compilable use case along with generated C code.
Thanks for taking time to report the bug. The generated code is correct as stated by comment 1. Please reopen the bug if needed by describing in more detail the problem you're experiencing.
Created attachment 169707 [details] GLib.List.sort() bug (vala)
Created attachment 169708 [details] GLib.List.sort() bug (*.c)
I'm not able to reproduce the bug I encountered with the TreeIterCompareFunc. But I reopen this bug because I have exactly the same problem with List.sort () and its CompareFunc. bug_sort.vala and bug_sort.c are attached. Here is the output: $ ./bug_sort ** (process:14002): CRITICAL **: test_on_compare: assertion `b != NULL' failed ** (process:14002): CRITICAL **: test_on_compare: assertion `b != NULL' failed world hello goodbye In the *.c file we can see that there is no wrapper function for test_on_compare (). If we declare on_compare () static, it's ok. Tested with Vala 0.9.8.
When you cast you're basically telling the compiler that you know better than it does, and you really want to use something as the specified type, even if the compiler thinks it is a bad idea. Therefore, when you cast to a delegate type Vala doesn't generate a wrapper function. If you're using the stable branch (0.10), you could do something like this: private int on_compare (void* a, void* b) { return ((string) a).collate ((string) b); } And don't cast the delegate. If you are using git, your code should work once you remove the cast, since comparison functions now use generic delegates.
I'm sorry to reopen this bug but it still doesn't work. I'm using Vala from git. Here is the relevant code: list.sort (on_compare); ... private int on_compare (string a, string b) { return a.collate (b); } And here is the result: $ valac bug_sort.vala bug_sort.vala:9.20-9.29: error: Argument 1: Cannot convert from `Test.on_compare' to `GLib.CompareFunc<string>' list.sort (on_compare); ^^^^^^^^^^ Compilation failed: 1 error(s), 0 warning(s) With the cast, the compilation works but it's the same problem as above: $ ./bug_sort ** (process:12697): CRITICAL **: test_on_compare: assertion `b != NULL' failed ...
Created attachment 171982 [details] test case Here is a test case which works fine. If you want on_compare to be an instance method you need to either make it static or use GLib.List.sort_with_data.