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

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Dmitry Bely <dbely@m...>
Subject: Re: [Caml-list] CamlIDL and function pointers
Xavier Leroy <xavier.leroy@inria.fr> writes:

>>   How would one annotate the following C struct for camlidl:
>> 
>> typedef struct funp {
>>    int i;
>>    void (*funp_fun) ();
>> } funp_t;
>> 
>>   Is it possible? Looking at the specs I don't see how one can have a
>> field that is a pointer to a function. Any ideas, or pointers (no pun
>> intended) to examples?
>
> CamlIDL, like the DCE and Microsoft IDL from which it derives, doesn't
> support exchanging function pointers between C and Caml.  Your best
> bet is to declare funp_t as an abstract type in the IDL file:
>
>         typedef [abstract] struct funp * funp_t;

I was able to make a normal C function pointer form Ocaml closure using the
"trampoline" technique and ffcall library from 
http://clisp.cons.org/~haible/packages-ffcall.html

Here is the working example from my HighGUI binding (a library from OpenCV
distribution):

Original C definition:

void (*HG_on_notify)(int);
int cvvCreateTrackbar( const char* name, const char* window_name,
                                   int* value, int count, HG_on_notify on_notify );

My IDL definition:

typedef [abstract,mltype("int->unit")] void* ON_NOTIFY; // void (*ON_NOTIFY)(int)
quote(c,"\
#include <callback.h>                                \n\
static int _slider_val;                              \n\
static void _ON_NOTIFY (void* cback, va_alist alist) \n\
{                                                    \n\
  int handle;                                        \n\
  va_start_void(alist);                              \n\
  handle = va_arg_int(alist);                        \n\
  callback(*(value*)cback,Val_int(_slider_val));     \n\
  va_return_void(alist);                             \n\
}")

int cvvCreateTrackbar([string] const char* trackbar_name, [string] const char* window_name,
                         [ref,in] int* val, int count, ON_NOTIFY call_back)
quote(call,"\
{                                                                                   \n\
  value* p_call_back;                                                               \n\
  __TR_function cback;                                                              \n\
  p_call_back = stat_alloc(sizeof(value));                                          \n\
  *p_call_back = _v_call_back;                                                      \n\
  register_global_root(p_call_back); /*both caml and C closure will live forever */ \n\
  cback = alloc_callback(_ON_NOTIFY, p_call_back);                                  \n\
  _slider_val = *val;                                                               \n\
  _res = cvvCreateTrackbar(trackbar_name,window_name,&_slider_val,count,cback);     \n\
}");

Now you can pass the normal OCaml closure to C function:

let f_sl1 x = print_string "slider 1:"; print_int x; print_newline ();;
cvvCreateTrackbar "sl1" "test_window" 5 10 f_sl1;;

- Dmitry Bely


-------------------
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