Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Automatic wrapper generator
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: skaller <skaller@u...>
Subject: Re: [Caml-list] Automatic wrapper generator
On Wed, 2004-05-19 at 03:21, Michael Hamburg wrote:
> >
> > It sounds very similar to Perl4caml, 

> I don't know how Perl's reference-counting scheme works, but I'm  
> working on interfacing O'Caml with Cocoa, 

Both these problems are more difficult than interfacing
Ocaml with C, if only because there are THREE languages
involved, and C is only the glue in between. So there
is a requirement to translate object models and memory
models.

A low level C/Ocaml interface is simpler by simply
specifying NO translations or memory model changes.

It's typical to desire stub functions that map
data types across boundaries. The approach I'm using
is to simply NOT do this at all.

Instead, you can write the type conversions as
auxilliary functions in C, which can be called
from Ocaml:

	let s = c_str "Ocaml string" in
	let d = c_malloc (200) in
	c_strcpy(d,s);

Note that the conversion from an Ocaml string to a 
C string (null terminated char pointer thingo) is done
by a separate function, this has nothing to do with
the wrapped up functions c_strcpy and c_malloc.

Any memory management issues that arise from using
c_str, c_malloc, and c_strcpy are the clients.
The FFI makes no attempt to do any memory management,
it makes no attempt to do any type conversions.

What makes this 'a good thing' is precisely how
totally brain dead it is. You know excactly what it will
do -- the same thing the underlying C does (modulo
a need for boxing).

I think the boxing is transparent as follows:
When you need to pass a C struct to a function --
and I mean *pass by value* -- you actually have
a Caml pointer to a custom block. C code casts
the custom block to form the argument .. the C calling
convention will copy it onto the stack.

At this point, if the custom block becomes unreachable
it gets collected, but that does not matter: C has a
copy on the stack. Returning a value requires copying
the struct off the stack into a custom block,
and returning a pointer instead, again, managed by Ocaml.

Pointers themselves are values .. so the above applies
to them too the same way. It should all work just fine
because C *only* allows pass by value: the C *never*
sees anything actually inside a custom block, it only
ever sees a copy.

There is no nesting. When you pass a pointer to an array,
the pointer is boxed. Ocaml owns the box, the pointer is copied
onto the stack and is owned by C, and the array is owned
by whoever created it .. typically C, and probably malloc.
The array itself doesn't live in a custom block so it isn't
managed by Ocaml, rather it is managed by C + client Ocaml code,
the latter by calling C .. 

As far as I can see this has to work in all cases,
it simply cannot fail and the wrapper can be generated
completely automatically. Of course the client Ocaml code
can 'free' a null pointer just the same can be done
with the equivalent C code: the assurance the wrapper
generator works comes from a simple isomorphism which 
also ensures all the faults of the C memory management
methods are also reflected.

The big plus here is that you can simply use any C library
from Ocaml 'as if writing C' so there is nothing to learn
about a complex new safe interface.

I expect *some* typemapping might be possible: certainly
where the object models coincide it may be possible
to skip the abstraction and just pass the common native
representation around, but I think that's limited to
some numeric cases plus some system types (like unix
file handles perhaps?)

BTW: Felix doesn't generally use boxing, so it will be 
at least one level of indirection faster than Ocaml.
It might be more though, since 'inlining' is still possible
with Felix, since it generates source and the underlying
C compiler can still do it's own optimisations.
So for Felix, the term 'Foreign Function Interface' is slightly
misleading, since C functions aren't foreign, and the wrapping
is primarily syntactic sugar including type annotations,
rather than requiring anything executable. The principal cost
is the loss of automatic intensional polymorphism
(since that requires boxing .. )

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners