Memory Management

The objects in cairo can roughly be divided into two types: reference-counted, opaque types like cairo_surface_t and plain structures like cairo_glyph_t. cairo_path_t and cairo_path_data_t are special cases and are treated separately in this appendix.

Refcounted opaque types all have a ..._reference() function to increase the refcount by one and a ..._destroy() to decrease the refcount by one. These should not be exposed to the user of the language binding, but rather used to implement memory management within the language binding. The simplest way to do memory management for a language binding is to treat the language binding object as a simple handle to the cairo object. The language binding object references the cairo object, and unreferences it when finalized. This is the recommended method, though there are a couple of caveats to be noted:

When a plain structure is used as a return value from cairo, this is done by passing it as a “out parameter”.

cairo_font_extents_t extents;      

cairo_font_extents (cr, &extents);

In a language binding, this should typically be treated as a return value:

FontExtents extents = cr.fontExtents ();

A language binding has a choice in how it implements the language objects for plain structures. It can use a pure language object with fields corresponding to those of the C structure, and convert from and to the C structure when calling cairo functions or converting cairo return values. Or it can keep a pointer to the C structure internally and wrap it inside a language object much like occurs for refcounted objects. The choice should be invisible to the user: they should be able to imagine that it is implemented as a pure language object.