If you’re interfacing with Vala code from C, it’s possible that you’ll have to make calls to libgee, a Vala data structure library. libgee is written in Vala, but its C API is perfectly usable once you get your head around the idioms.
A common idiom is that of the GeeIterator, which is the recommended way to iterate through sets, maps and lists (which all implement the GeeIterable interface). For a loop, you create a new GeeIterator, then call its get and next methods to retrieve the object for the current iteration and advance to the next iteration, respectively.
For example, to list all the phone numbers in a FolksIndividual:
GeeSet *phone_numbers; GeeIterator *iter; FolksPhoneDetails *details; details = FOLKS_PHONE_DETAILS (my_individual); phone_numbers = folks_phone_details_get_phone_numbers (details); iter = gee_iterable_iterator (GEE_ITERABLE (phone_numbers)); while (gee_iterator_next (iter)) { FolksPhoneFieldDetails *details; gchar *number; /* Get the current iteration’s element. * Note that ownership is transferred. */ details = gee_iterator_get (iter); number = folks_phone_field_details_get_normalised (details); g_message ("Phone number: %s", number); g_free (number); g_object_unref (details); /* important! */ } g_object_unref (iter); /* important! */
One key thing to note here is that the return values from gee_iterator_get() and gee_iterable_iterator() are transfer-full and need to be unreffed. Failing to unref them is a common mistake when using libgee from C, and results in leaked objects — and was the cause of several memory leaks recently fixed in Empathy. When using libgee from Vala this isn’t a problem, since the memory management is handled automatically.
This has been a public service announcement.
As a side note - while
GeeIterator
is backward-compatible form it is not the only one. In libgee 0.8 agee_traversable_foreach
which a) have arguably more C-memory friendly way of handling the resources (no unrefing except collection) and b) are faster to various degree given a collection. From C they are slightly harder to use though (separate method).I thought about introducing something like
gee_iterator_peek
for performance reason in 0.14 but I need to think how to do it without breaking API."Failing to unref them is a common mistake when using libgee from C, and results in leaked objects — and was the cause of several memory leaks recently fixed in Empathy."
I'm about to improve generated C documentation. Specially for memory management and generics.