Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
CamlIDL: Returning a whole array of cows
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2007-09-17 (20:10)
From: Jakob Lichtenberg <jakobl@w...>
Subject: CamlIDL: Returning a whole array of cows
1. Summary: Stub code generated by Camlidl seems to call camlidl_malloc
with an uninitialized size.



2. Details:


I am declaring a function 'void get_cows([out] int* len,
[length_is(*len), size_is(*len), out] cow** cows);' that creates and
returns an array of cows.  (Each cow is just a pointer to a structure.)
The generated stub code seems incorrect:



value camlidl_cow_get_cows(value _unit)


  int *len; /*out*/

  cow **cows; /*out*/

  int _c1;

  mlsize_t _c2;

  value _v3;

  value _vres;


  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };

  camlidl_ctx _ctx = &_ctxs;

  len = &_c1;

  cows = camlidl_malloc(*len * sizeof(cow *), _ctx);

  get_cows(len, cows);

  _vres = camlidl_alloc(*len, 0);


    for (_c2 = 0; _c2 < *len; _c2++) {

      _v3 = camlidl_c2ml_cow_cow(&*cows[_c2], _ctx);

      modify(&Field(_vres, _c2), _v3);




  return _vres;



As you can see camlidl_malloc is called with an uninitialized value. 


Is this a bug in camlidl, or am I writing my IDL file incorrectly.
Another way to ask:  How do I declared that a function reserves an array



3. Implementation details:


This is my C api I'd like to access from ocaml:



typedef struct _cow {

  char* name;

  int age;

} *cow;


cow get_dummy_cow();


void get_cows_inout(int inputlen, int *outputlen, cow ca[]); // Write
cows to 'ca', however not more than 'inputlen' elements.  Write number
of cows written to '*outputlen'.


void get_cows(int* len, cow **ca); // Malloc array for cows.  Save
number of elements to *len, save address for array in '*ca'.


void print_cow(cow o);


I'd like to access this API from OCaml using CamlIDL.  I use the
following idl file:



typedef [abstract] void* cow;


[pointer_default(ref)] interface Cow {


cow get_dummy_cow(void);


void get_cows_inout([in] int inputlen, [out] int * outputlen,

                    [in,out,size_is(inputlen),length_is(*outputlen)] cow


void get_cows([out] int* len, [length_is(*len), size_is(*len), out]
cow** cows);


void print_cow(cow o);




I compile this using:


                camlidl cow.idl


And use it from the following ML program:

let main use_inout =

  let cows =

    if use_inout then Cow.get_cows_inout(Array.create 3

    else Cow.get_cows()


  Array.iter Cow.print_cow cows


let _ = main true;


This works fine.  However, if I change the call to main to 'main false'
I get a crash.  




-          Jakob


PS. I know that I am leaking memory - that I can fix with a simple
quote(dealloc, "free(*cows);");