Thanks to everyone who replied.
I'll be a bit more specific about what I'm trying to do and where I'm
having problems. The bindings are for newt, a text widget library.
This is the sparsely documented header file:
http://www.annexia.org/tmp/newt.h.txt
Specifics:
(1) Newt has a 'newtComponent' object. Components can be general
widgets like entry boxes, buttons and so on. Or they can be grids or
forms, both of which contain (recursively) other components.
The internals of the C library have absolutely zero type checking --
if you pass a button component to a function like newtFormSetSize
which expects a form, then it will probably segfault.
A high quality binding would use phantom types to enforce the types,
so:
val newtForm : ... -> [`Form|`Component]
val newtFormSetSize : [>`Form] -> unit
It's very hard to annotate this in camlidl (actually impossible - I
didn't find any way to do it satisfactorily).
(2) Newt uses callbacks, but it seems that function pointers aren't
implemented by camlidl.
(3) Newt lets you attach data to some components:
void newtListboxSetData (newtComponent co, int num, void *data);
void *newtListboxGetCurrent (newtComponent co);
High quality bindings like lablgtk make complex use of polymorphic
types to allow you to store and retrieve data safely, but for the
simpler listbox case above we might just want (ignoring my phantom
types above):
type 'a listbox
val newtListboxSetData : 'a listbox -> int -> 'a -> unit
val newtListboxGetCurrent : 'a listbox -> 'a
(4) NULL pointers & exceptions: If you bind pointers using [ref] then
you get a segfault when a function returns NULL (eg. indicating an
error). But if you don't do that you have to deal with Some/None
everywhere.
(5) Flags:
#define NEWT_FLAG_RETURNEXIT (1 << 0)
#define NEWT_FLAG_HIDDEN (1 << 1)
#define NEWT_FLAG_SCROLL (1 << 2)
Obviously these are meant to be or-ed together.
(6) A bunch of minor things:
- const correctness, camlidl doesn't have it
- unions -- are they supported at all?
- varargs?
OK so enough complaining. What I was thinking of doing was using
camlidl straight (as far as it goes) to make an unsafe NewtInt
internal binding, then wrapping a hand-written OCaml binding on top
which gives all the good stuff like type safety, finalization and
exceptions.
At this point I'm not sure how much work I'm saving ...
Rich.
--
Richard Jones
Red Hat
.