Version française
Home     About     Download     Resources     Contact us    
Browse thread
Using the C FFI to wrap an OCaml library
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Joel Stanley <jstanley@g...>
Subject: Re: [Caml-list] Using the C FFI to wrap an OCaml library
>>>>> Damien Doligez writes:

>> Looking at the macro expansions, I'm suspicious about the safety between
>> C functions,

> Could you elaborate on what makes you say that?  The macros carefully
> implement a stack discipline designed for nested calls.

Well, much of my curiosity stems from the fact that I know little about
the OCaml runtime or how the OCaml GC is invoked.  If the GC can ever be
invoked in its own thread, it seems like while the values (of type
'value') are being passed back on the stack (but *after* the
caml__local_roots pointer has been reverted) there could be problems?

If this can't ever happen, great! Why not?

>> 2. As a follow-up question to #1, the OCaml values may need to be
>> carried across yet another FFI, in this case, C <-> Poly/ML .  Even if
>> using the macros was a safe way to carry values between C functions, I"m
>> not sure I can easily replicate the macros on the other side of the FFI,
>> so am wondering if an explicit memory management approach using
>> caml_register_global_root will work.  E.g.,
>> 
>> value* alloc_value() {
>> value* p = malloc(sizeof(value));
>> caml_register_global_root(p);
>> return p;
>> }

> In order to make this work, you have to explain to Poly/ML that every
> access to the value must be done through the value*...I think it's
> more reasonable to just copy the data between worlds instead of trying
> to share pointers between OCaml and Poly/ML.

So let's talk about a concrete example here.  Let's say that I have some
dynamically-allocated object on the OCaml heap (for discussion purposes,
say it's an instance of some simple 'stack' class) and that I've
returned a reference to that object to a C function.  Are you saying
that the stack contents (e.g., a deep copy of my object) themselves are
marshaled across this boundary every time?

What about, perhaps, having an object registration mechanism on the
OCaml so that a newly-allocated object's reference goes into a (global)
hash table, and an opaque handle (e.g., some fresh, unique integer
value) is yielded back to C land?  This would require an explicit
deallocation (just passing the handle back) to come from the C side, but
should keep the heap object around until such a deallocation call is
made.  Right?

Basically, the problem is that I have a large OCaml library that
constructs a variety of different types of objects and I would like a
1-1 correspondence between those objects and Poly/ML values that wrap
corresponding C volatiles.  I'd like to do this in the most
straightforward and safe way possible.

Thanks for your help,
Joel