Version française
Home     About     Download     Resources     Contact us    
Browse thread
How to raise_with_arg() a tuple?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Olivier Andrieu <andrieu@i...>
Subject: Re: [Caml-list] How to raise_with_arg() a tuple?
 Thomas Fischbacher [Thursday 7 July 2005] :
 >
 > 
 > Hello together,
 > 
 > I'd like to throw an exception from within C code which provides
 > more information to Caml than just a string.
 > 
 > If I do it that way:
 > 
 > === Caml ===
 > 
 > exception Test_exn of int * int

It's the usual gotcha with variant constructor that have multiple
arguments. The exception you defines has two arguments, whereas 

 exception Test_exn of (int * int)

has only one argument -- a tuple. It's not the same thing.

 > external test_raise_tuple: bool -> (int*int) = "caml_test_raise_tuple"
 > 
 > let _ = Callback.register_exception "ocaml_exn_test" (Test_exn (0,0));;
 > 
 > === C ===
 > 
 > CAMLprim caml_test_raise_tuple(value x)
 > {
 >   CAMLparam1(x);
 >   int cx;
 > 
 >   cx=Int_val(x);
 >   fprintf(stderr,"DDD x=%d\n",cx);
 > 
 >   CAMLlocal1(ex);
 >   ex=alloc_tuple(2);
 > 
 >   Store_field(ex,0,Val_int(2));
 >   Store_field(ex,1,Val_int(4));
 > 
 >   if(cx)
 >     {
 >       raise_with_arg(*caml_named_value("ocaml_exn_test"), ex);

here you are raising an exception with one tuple argument, this
doesn't match the exception you defined.

There's no function to directly create an exception value with
multiple argument, you have to do this (IIRC, not tested) :

  ex = alloc(3, 0);
  Store_field(ex, 0, *caml_named_value("ocaml_exn_test");
  Store_field(ex, 1, Val_int(2));
  Store_field(ex, 2, Val_int(4));
  caml_raise(ex);

 > ===>
 >  Your function may raise an exception or return a [value] with the
 >  [CAMLreturn] macro.  Its argument is simply the [value] returned by
 >  your function.  Do NOT directly return a [value] with the [return]
 >  keyword.  If your function returns void, use [CAMLreturn0].
 > <===

actually it's ok to raise exception directly (ie, not through
CAMLreturn), the runtime takes care of releasing the local GC roots.

-- 
   Olivier