Over the last couple of weeks I’ve been gradually pulling glibmm’s gio wrapper into shape. It provides a gtkmm-like API for the new gio I/O API in glib 2.15/16. It’s available in the glibmm 2.15.x tarballs, and will be API stable in glibmm 2.16 (Tarballs, svn).
There are a handful of giomm examples in the gtkmm-documentation module and we are adding more. Thanks to Marko Anastasov who did all the initial wrapping work and Jonathan Jongsma and José Alburquerque who have helped to perfect it.
It was quite awkward repetitive work because we had to add so many method overloads and reorder so many parameters, and write most of the documentation by hand (not finished yet). I feel most of the work is now done, so I’m less worried about impending API stability, but I still want more people to review the API and try to use it.
Some thoughts for people creating language bindings
Many gio functions take several arguments, half of which (such as the GCancellable, and sometimes the callback) can be NULL or have obvious defaults (such as G_IO_PRIORITY_DEFAULT, or G_FILE_QUERY_INFO_NONE, or “*” for attributes). It’s too late to reorder the parameters in the C API, but I strongly suggest that you try to copy the parameter sequences in the giomm methods. Replacing GError with an exception removes another parameter. For instance, compare Gio::File::query_info(), which can be called with no parameters, with g_file_query_info().
Some thoughts in general
I quite like the consistent approach to asynchronous operations. Basically, there are often two forms of a function – a synchronous one (blocks, returning when it has a result) and an asynchronous one (returns immediately, and tells you later when it has a result). For instance, g_file_query_info() and g_file_query_info_async(). With the async one, you then call the *_finish() (for instance, g_file_query_info_finish()) to get the result. See GFile (or Gio::File) for a full explanation.
For a while I wondered if some intermediate object would be conceptually more beautiful, so you wouldn’t have to read the documentation to know about the *_finish() method to call, but it seems worse. For instance:
async_request = file.query_info_async();
async_request.signal_finished().connect(&on_query_finished);
async_request.start(); //We would have to do this only after connecting the signal.
...
if(something happened)
async_request.cancel();
...
void on_query_finished(...)
{
...
result = async_request.get_result();
}