Generating C# interfaces the lazy way

on Wednesday, January 02, 2008
Since all this Winforms WebBrowser control / Mono.Mozilla / gluezilla business started, there's one thing that's been nagging me at that place in the brain where I store stuff I'd rather not think about at the moment (and yes, it's a place that quite resembles those junk-filled attics you see in movies where the kids go to play and occasionally encounter old moth-eaten dresses, the occasional treasure map or your garden-variety skeleton of the aunt nobody had seen in 50 years - a stuffy, moldy place where you can't take a step without tripping on something...)...

Where was I? Oh, yes, nagging me was the thought that, while I had successfully created C# interfaces from the mozilla idl files, and was successfully accessing mozilla through XPCOM directly from the managed side, those interfaces were created by hand, which was not that hard at all, and I really could go on doing them by hand, only getting full DOM support on Mono.Mozilla would require generating some 50 interfaces... by hand.... ugh

So, whilst suffering without net last week due to a router dying and a firewall showing solidarity towards said router (i.e., dying too), I ran across some perl scripts that are being used for various tasks all over the mono tree, and decided that enough was enough, I should get it over once and for all and do a little script to parse the idl files and generate my badly needed interfaces.

Queue a fun-filled day playing around with perl, learning from scripts and from what little documentation I could find on my system (no net, no manuals...) In the end, scraped something together which is living on svn in mcs/class/Mono.Mozilla/tools/xpidl2cs

xpidl2cs basically parses an idl file and generates a C# interface that's ready to be used. It goes all the way up the inheritance tree and generates all parents and, since .NET interop doesn't support interface inheritance and requires child interfaces to also include all the declarations from the parent, xpidl2cs recursively includes all the parent declarations, so you end up with a (probably rather) huge but working interface.

xpidl2cs also generates all the interfaces that are used in methods and properties of your target idl (and parents) so that all dependencies are satisfied in one pass. To avoid endless looping on this, the script doesn't generate the interface if a .cs file with the same name already exists in the directory, so if you want to make sure everything is regenerated, you should rm all interfaces first.

The usage is simple: xpidl2cs.pl file.idl [/path/to/idl/files/]

Any bugs, comments, flames, etc, feel free to nag here or on the #mono channel over at irc.gnome.org, or just mail me.