Dub (Doxygen based Ubiquitous Binder)

This is a tool to ease the creation of scripting language bindings for a C++ library. It is currently developed to crete the OpenCV bindings for Lua in Rubyk (rubyk.org).

The generator uses the xml output from Doxygen to avoid parsing C++ code by itself.

Homepage: rubyk.org/en/project311.html


Currently, the parser supports:

* class methods
* overloaded class constructors
* overloaded class methods
* class instantiation from templates through typedefs
* class alias through typedefs
* automatic resolution of template parameters
* automatic handling of default values
* class enums
* namespace enums
* group constant defines
* bindings for superclass
* hand made bindings in yaml (this is used to do more 'natural' bindings for
  the target language)
* well tested
  in fact no, it was but the tests are not up to date and need fixing
  our best testing is that bindings run and compile without a warning or bug.

If you are not good at reading lists, here is an example of the kind of tricks Dub plays with types:

template<class T>
class Point_ {

template<class T>
class Size_ {
  Size_(const Point_<T>);
typedef Size_<int> Size2i;
typedef Size2i Size;

typedef Point_<int> Point2i;
typedef Point2i Point;

All these typedefs and templates will generate two class bindings with some aliases:

* <tt>Size</tt>, aliased as <tt>Size2i</tt>
* <tt>Point</tt>, aliased as <tt>Point2i</tt>

And what's really good is that in the definition for the Size constructor, Point_<T> is recognized as Point !

Using @dub

If you want to set class options inside the sources with the @dub tag, you need to set the ALIASES as follows in the Doxyfile:

ALIASES                = "dub=\par Bindings info:\n"

Then you can write settings in the class documentation:

/** Some class.
 * @dub string_format:'%%f'
 *      string_args:'(*userdata)->interval()'
 *      super: 'QObject, QWidget'
 *      bind: 'Foobar.yml'

Note that for some strange reason, you have to use a double '%' to get one.


The easiest way to deal with constants is through documented enums (if this is possible) or defines with @defgroup.

Custom destructors

By default Dub expects that the scripting app manages memory. This means that objects are deleted by the __gc method in Lua for example. If you want to allow destruction from both the scripting language and C++, you can subclass the C++ with DeletableOutOfLua (this protects Lua userdata from dangling pointers):

/** This class can be deleted from C++ or Lua
 * @dub destructor: 'dub_destroy'
class CustomDestructor : public DeletableOutOfLua
  // nothing special here

Once a custom destructor is set, the method calls in Lua are protected (check that the object still exists). You also get a new method “deleted” that returns true if the C++ is … well, yes: deleted.

You can also disable destruction from the scripting language by setting “destructor: ''” (empty string).

Cucstom constructors

You can use custom constructors by using a static member function:

/** This class can be deleted from C++ or Lua
 * @dub constructor: 'BuildCar'
class Car
  static LuaStackSize BuildCar(lua_State *L);

Note that we have used the two special return values and parameters so that we can be in full control (this also means we will need to push the userdata on the stack before returning the stack size). The LuaStackSize is a typedef for int.