From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.6 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE, HTML_MESSAGE,SPF_SOFTFAIL autolearn=disabled version=3.1.3 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 5863BBC6B for ; Mon, 5 Nov 2007 19:32:05 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAALvvLkfAXQImh2dsb2JhbACCc4wHAQEBCAop X-IronPort-AV: E=Sophos;i="4.21,373,1188770400"; d="scan'208,217";a="4071039" Received: from discorde.inria.fr ([192.93.2.38]) by mail1-smtp-roc.national.inria.fr with ESMTP; 05 Nov 2007 19:32:05 +0100 Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id lA5IW4nZ022499 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Mon, 5 Nov 2007 19:32:04 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAG7wLkeDa3PXn2dsb2JhbACCc4wHAQEBAQcEBgkIGA X-IronPort-AV: E=Sophos;i="4.21,373,1188770400"; d="scan'208,217";a="3923199" Received: from mailb.microsoft.com (HELO smtp.microsoft.com) ([131.107.115.215]) by mail2-smtp-roc.national.inria.fr with ESMTP; 05 Nov 2007 19:32:04 +0100 Received: from tk1-exhub-c103.redmond.corp.microsoft.com (157.56.116.114) by TK5-EXGWY-E802.partners.extranet.microsoft.com (10.251.56.168) with Microsoft SMTP Server (TLS) id 8.1.222.3; Mon, 5 Nov 2007 10:31:52 -0800 Received: from TK5-EXMLT-W604.wingroup.windeploy.ntdev.microsoft.com (157.54.18.7) by tk1-exhub-c103.redmond.corp.microsoft.com (157.56.116.114) with Microsoft SMTP Server id 8.1.222.3; Mon, 5 Nov 2007 10:32:02 -0800 Received: from NA-EXMSG-W601.wingroup.windeploy.ntdev.microsoft.com ([fe80::5efe:10.255.255.1]) by TK5-EXMLT-W604.wingroup.windeploy.ntdev.microsoft.com ([157.54.18.7]) with mapi; Mon, 5 Nov 2007 10:32:02 -0800 From: Jakob Lichtenberg To: "caml-list@inria.fr" Date: Mon, 5 Nov 2007 10:31:58 -0800 Subject: FW: CamlIDL: Returning a whole array of cows Thread-Topic: CamlIDL: Returning a whole array of cows Thread-Index: Acf5ZuWi+m+8hSugQum/0jymdenemQmcv1/g Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: multipart/alternative; boundary="_000_DACB514F44E4864CAFDC7DAD144A7E6CBC1FB2A05FNAEXMSGW601wi_" MIME-Version: 1.0 X-Miltered: at discorde with ID 472F61A4.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; camlidl:01 camlidl:01 stub:01 malloc:01 pointer:01 stub:01 stubs:01 mlsize:01 struct:01 struct:01 ctxs:01 ctxs:01 malloc:01 sizeof:01 alloc:01 --_000_DACB514F44E4864CAFDC7DAD144A7E6CBC1FB2A05FNAEXMSGW601wi_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Resending due to no answer. - Jakob From: Jakob Lichtenberg Sent: Monday, September 17, 2007 1:11 PM To: 'caml-list@inria.fr' Subject: CamlIDL: Returning a whole array of cows 1. Summary: Stub code generated by Camlidl seems to call camlidl_malloc wit= h 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 se= ems incorrect: cow_stubs.c: 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 =3D { CAMLIDL_TRANSIENT, NULL }; camlidl_ctx _ctx =3D &_ctxs; len =3D &_c1; cows =3D camlidl_malloc(*len * sizeof(cow *), _ctx); get_cows(len, cows); _vres =3D camlidl_alloc(*len, 0); Begin_root(_vres) for (_c2 =3D 0; _c2 < *len; _c2++) { _v3 =3D camlidl_c2ml_cow_cow(&*cows[_c2], _ctx); modify(&Field(_vres, _c2), _v3); } End_roots() camlidl_free(_ctx); 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: cow.h: 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 w= ritten to '*outputlen'. void get_cows(int* len, cow **ca); // Malloc array for cows. Save number o= f 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: cow.idl: 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 d[= ]); void get_cows([out] int* len, [length_is(*len), size_is(*len), out] cow** c= ows); void print_cow(cow o); } I compile this using: camlidl cow.idl And use it from the following ML program: mlmain.ml: let main use_inout =3D let cows =3D if use_inout then Cow.get_cows_inout(Array.create 3 (Cow.get_dummy_cow(= ))) else Cow.get_cows() in Array.iter Cow.print_cow cows let _ =3D main true; This works fine. However, if I change the call to main to 'main false' I = get a crash. Thanks, - Jakob PS. I know that I am leaking memory - that I can fix with a simple quote(de= alloc, "free(*cows);"); --_000_DACB514F44E4864CAFDC7DAD144A7E6CBC1FB2A05FNAEXMSGW601wi_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Resending due to no answ= er.

 =

- Jakob

 =

From: Jakob Lichten= berg
Sent: Monday, September 17, 2007 1:11 PM
To: 'caml-list@inria.fr'
Subject: CamlIDL: Returning a whole array of cows
<= /p>

 

1. Summary: Stub code generated by Camlidl seems to ca= ll camlidl_malloc with an uninitialized size.

 

 

2. Details:

 

I am declaring a function ‘void get_cows([out] i= nt* 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:

 

cow_stubs.c:

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 =3D { CAMLIDL_TRANSIENT, NULL };

  camlidl_ctx _ctx =3D &_ctxs;

  len =3D &_c1;

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

  get_cows(len, cows);

  _vres =3D camlidl_alloc(*len, 0);

  Begin_root(_vres)

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

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

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

    }

  End_roots()

  camlidl_free(_ctx);

  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 funct= ion reserves an array

 

 

3. Implementation details:

 

This is my C api I’d like to access from ocaml:<= o:p>

 

cow.h:

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 arr= ay 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 Cam= lIDL.  I use the following idl file:

 

cow.idl:

typedef [abstract] void* cow;<= /p>

 

[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 d[]);

 

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:

 

mlmain.ml:

let main use_inout =3D

  let cows =3D

    if use_inout then Cow.get_cows_inout(Array.create 3 (Cow.get_dummy_cow()))<= /p>

    else Cow.get_cows()

  in

  Array.iter Cow.print_cow cows<= /span>

 

let _ =3D main true;

 

This works fine.  However, if I change the call t= o main to ‘main false’= ;  I get a crash. 

 

Thanks,

 

-&nb= sp;       Jakob

 

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

--_000_DACB514F44E4864CAFDC7DAD144A7E6CBC1FB2A05FNAEXMSGW601wi_--