Re: Second draft (was Re: defs files)




I have some serious reservations about the way that types are handled
in this proposal. 

The original defs file format took the approach that there were
conceptual abstract types (object, boxed, struct, flags field), which,
when combined with a directional description (in, out, inout), have a
mapping into C which is reflected in the C headers.

This conceptually very much like the way that CORBA works. 

Now, there is one problem with this approach, which is that there are
some inconsistencies in the GTK+ API, and there are some parts of the
GTK+ API that don't translate naturally into things other than C,
and which need manual wrapping in many language bindings.

So, your proposal takes a very different approach, which is simply to
reformat C types in a way that is slightly more convenient to
parse. (You've added sugar and aliases to make it look a bit more like
the first approach, but I don't think that this is a
mischaracterization.)

I'm not in favor of this:

 - There _is_ semantic information beyond the simple C types.
   For instance, the information that a returned char * must be freed.

 - The C type representation may not be unique. For instance, is 
   'GtkWidget **' 'out GtkWidget *' or 'array of GtkWidget *' you
   can't tell.

   We can disambiguate this in the header files by adding magic comments,
   but if your defs file format is build around C types, then you'll
   need some clumsy way of disambiguating it there too.

 - I don't fully understand your proposed mapping between C types
   and type names, but it seems to be rather ambiguous in a few
   places. 

   - If you mean to preserve the current approach in the defs file of
     converting '_' to '-' in all names, then you don't even have a
     unique mapping.

   - It's not at all clear what you do with complex declarations
     with (), [], function declarations, etc.

If you need to preserve the original C types for the C-specific parts
of the GTK+ API, then you should simply preserve the actual C declarations
with something like:

   (function cmap_new
     (in-module (Gdk Rgb))
     (c-name gdk_rgb_cmap_new)
     (return-type GdkRgbCmap*)
     (parameter (type-and-name native colors)
                (c-declaration "guint32 *colors"))
     (parameter (type-and-name gint n_colors)))

[...]

> ===
> (boxed boxed-name
>   (in-module modname)
>   (c-name c-name)
>   (by-value-ok boolean-can-just-memcpy)
>   (ref-func func-to-increase-refcount)
>   (unref-func func-to-decrease-refcount)
>   (copy-func func-to-copy)
>   (destroy-func func-to-destroy)
>   (field (type-and-name type-alias-of-struct-field name-of-struct-field)))

You need to merge the (destroy...) and (unref-func...) to be simply
(release...). It's possible that ref-func and copy-func should be kept
separate, since they encapsulate a distinction between a shallow copy
and a deep copy. However, I'm not really sure that is valuable either,
because these type descriptions are meant to be used for the purposes
of internal memory management of the language binding, so one or the
other should be picked, and it should be consistent between language
bindings.

Also, I think that structures-by-value should be separated from boxed
types - they are conceptually different, and they also map into C
slightly differently. For instance:

 void GdkRectangle::intersect (GdkRectangle rect1, GdkRectangle rect2, out GdkRectangle dest)

Does not map into C as:

 void gdk_rectangle_intersect (GdkRectangle *rect1, GdkRectangle *rect2, GdkRectangle **dest)

But rather as:

 void gdk_rectangle_intersect (GdkRectangle *rect1, GdkRectangle *rect2, GdkRectangle *dest)

The memory for the out parameter is allocated by the caller. 

Regards,
                                        Owen



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