Re: Perl bindings for tinymail, the first pieces



[Cross-posted to gtk-perl-list in case anyone over there is interested in a binding project.]

On Nov 28, 2006, at 3:32 PM, Philip Van Hoof wrote:

In an attempt to get people interested in Perl bindings for tinymail,
I've created the maps files of libtinymail, libtinymailui,
libtinymail-camel and libtinymailui-gtk.

There should also be a generated maps file for the selected platform
specific library (for example for libtinymail-gnome-desktop,
libtinymail-olpc, libtinymail-maemo or libtinymail-gpe)

I have no idea what more I should do. I have not in-depth looked at its
documentation. I can't put a high priority on this for myself. I will
assist anybody who tries, or plans to spend some time on it.


I have neither the requirements for building tinymail nor the time to devote to doing the bindings (thanks to $dayjob and family), but I'd be happy to consult anyone who wishes to.

To kick things off, i have created a completely untested (not even compiled) XS implementation of TnyFolder and TnyFolderIface. I did this by copying tny-folder.h to TnyFolder.xs and hacking away. Functions that require no special work are as simple as C prototypes. The ones that gave me trouble were tny_folder_refresh_async(), which requires two callbacks but only one user data parameter, and its brother, TnyFolderIface::refresh_async_func, which must give to a perl developer an invokable handle to a C function, with user data destruction. The code is nontrivial, but mostly bog-standard XS with gtk2-perl conventions, and i've commented the truly scary parts.


Some documentation (the author in in CC of this E-mail)

http://search.cpan.org/~tsch/Gtk2-1.141/devel.pod
http://search.cpan.org/~tsch/Gtk2-1.141/CodeGen.pm

I knew that putting my name on that stuff would get me into trouble. ;-)

Unfortunately, the special techniques for wrapping GInterfaces are not described in those documents, because it is, ahem, a rather manual process. I'll try to give some good info here, so pardon the length.

First, a little background:

The GType system has a limited reflection capability intended to support signals and properties. Some work has been done towards providing full API introspection capability, through API metadata generated at compile time and stored in an ELF section of the library; however, this work has yet to reach a usable state of completeness. Also, at the time that we created Gtk2-Perl, this work hadn't even been conceived.

We chose to write the binding in plain old XS. XS is perl's eXternal Subroutine language, a mixture of C and a minilanguage that gets expanded into C code by the xsubpp program as part of perl's extension building machinery. With these tools, writing bindings for most of the GNOME stack has been quite easy. Some corner cases of the GNOME / GTK+ API style cause the amount of hand-written code to go up, but for most APIs, made of getter and setter functions with simple semantics, the bindings are rather rote.

But, from a quick look at the tinymail headers, I'm afraid to say that the tinymail API leans heavily on those parts of the API style that cause the amount of hand-written code to go up: GInterfaces and GErrors.

The use of GError in a function requires that you trap that value and turn it into a perl exception. There's not a good hook built into xsubpp for this, so you write the methods out by hand. It gets even messier when dealing with GErrors passed through callbacks.

GInterfaces are one area of the binding that we were never able to automate satisfactorily. The basic problem is that you have to hand- roll a marshaler for every one of the members of the vtable, because there is no introspection information for them. On the other hand, this works out nicely for users, because implementing GInterfaces is actually easier and more perlish than some of the other aspects of implementing a GObject in perl. (In perl, a function that is invoked indirectly is typically given an ALLCAPSNAME. We couldn't do this for signal overrides, because these names can be anything, and have potential to collide with reserved names, such as DESTROY. But, since binding an interface is manual, the binding implementor gets a chance to fix any such name clashes.)


But, now that i've said all that scary stuff, i'll also say that it's not really that hard. It'll be a fair amount of work, but there's an IRC channel (#gtk-perl on irc.gnome.org) and mailing list (gtk-perl- list gnome org) and lots of example code to go by, so help isn't far away.



Attachment: TnyFolder.xs
Description: Binary data



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]