English version
Accueil     À propos     Téléchargement     Ressources     Contactez-nous    

Ce site est rarement mis à jour. Pour les informations les plus récentes, rendez-vous sur le nouveau site OCaml à l'adresse ocaml.org.

Browse thread
[Caml-list] dynamically loading C functions
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2001-03-05 (20:28)
From: Chris Hecker <checker@d...>
Subject: [Caml-list] dynamically loading C functions

I'm looking into dynamically linking to C functions "mostly" type safely, and I've run into a couple small snags:  

1.  I need to generate the thunk (or trampoline, it's sometimes called) to convert the caml values to their C values.  Assume I've found some way (see below) to tell the library what function I'm linking to, and what it's type it is supposed to be.  I need to generate a thunk (at runtime) that converts the caml versions of the parameters to the C versions.

For example, say I've got this:

(* int TheFunction( double, double ); ... ignore how I'm typing 
   get_function for until below *)
let f = get_function "TheFunction" "float -> float -> int"

So, if I'm going to be able to call f from caml, get_function is going to need to generate a stub that takes two values and returns a value, and converts those to their C types with the mlvalues.h macros before calling TheFunction (and handles its return type).

This piece of magic doesn't have to be very smart, since it's going to be predefined chunks of conversion code, but it will have to be generated on the fly by piecing together these chunks if I'm really going to allow completely dynamic linking.

This is obviously not very cross platform.  There is a library called ffcall which has a thing called avcall in it that looks like it might do what I want with some massaging, and it's cross platform.   

I think I also need to worry about generating the function that gets called directly by the return of get_function, but I think I can use the ffcall vacall library for that.

Does anybody have any experience with avcall, vacall, or ffcall?  Is there a better way to do this?

2.  I want to have get_function return a correctly typed function that can just be called with the correct caml types.  So, in the example above, f should be float -> float -> int.  There are two parts to this problem:  I need to have the source code specify the type of the linked function to the link library so it can generate the thunk as above, and I need to specify the type of the return function to the caml compiler.

I think I have a few options:

- I can try to use the printf formatting stuff and try to get this to do the right thing, so you'd pass a format string to the function.  This has problems with return values, since those aren't read from the format string.  I can do

val get_function: ('a,unit,'c) format -> 'c -> 'a

and that will work, but it requires me to pass in a dummy parameter for 'c to get it to parameterize 'a correctly on return type.  Is there a good way to specify types for this sort of thing?  Maybe use the format string for the parms and some kind of explicit specification for the return type?  But get_function needs to return 'a as its return type...

- I can just have val get_function: string -> 'a, and have it parse the string internally to get the type, and then let 'a be type inferred in the caml source from the use of the return value.  Is that a good idea?  It seems like that might make for ambiguities if you ignore return values or curry it.

- I can tell people to "cast" the 'a return type, so you'd do this:

let f = (get_function "TheFunction: float -> float -> int" : float -> float -> int)

but, this requires the error prone double-specification of the type, once to the library, and once to the source code.

It seems to me that the printf format string one is "cleanest" and type-safest, but the return value thing is a hack.  I guess I could also patch the compiler and extend the format string parser to take a special % token to specify a return type, but that would be a hack itself and a lot of work.

Any ideas?  And yes, this all goes away if I have a preprocessing step that generats the caml/c interface, but I'd really like to be able to do this at runtime.


To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr