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=0.8 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE autolearn=disabled version=3.1.3 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id D7569BC6B for ; Mon, 5 Nov 2007 22:35:57 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAGUbL0fAXQInh2dsb2JhbACOegEBAQgKKYEP X-IronPort-AV: E=Sophos;i="4.21,374,1188770400"; d="scan'208";a="18967698" Received: from concorde.inria.fr ([192.93.2.39]) by mail4-smtp-sop.national.inria.fr with ESMTP; 05 Nov 2007 22:35:57 +0100 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id lA5LZuRi007290 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Mon, 5 Nov 2007 22:35:57 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAFMbL0eDa3PWn2dsb2JhbACOegEBAQEHBAYJCBiBDw X-IronPort-AV: E=Sophos;i="4.21,374,1188770400"; d="scan'208";a="4076787" Received: from mailc.microsoft.com (HELO smtp.microsoft.com) ([131.107.115.214]) by mail1-smtp-roc.national.inria.fr with ESMTP; 05 Nov 2007 22:35:56 +0100 Received: from TK5-EXHUB-C102.redmond.corp.microsoft.com (157.54.70.72) by TK5-EXGWY-E803.partners.extranet.microsoft.com (10.251.56.169) with Microsoft SMTP Server (TLS) id 8.1.222.3; Mon, 5 Nov 2007 13:35:44 -0800 Received: from TK5-EXMLT-W603.wingroup.windeploy.ntdev.microsoft.com (157.54.18.6) by TK5-EXHUB-C102.redmond.corp.microsoft.com (157.54.70.72) with Microsoft SMTP Server id 8.1.222.3; Mon, 5 Nov 2007 13:35:54 -0800 Received: from NA-EXMSG-W601.wingroup.windeploy.ntdev.microsoft.com ([fe80::5efe:10.255.255.1]) by TK5-EXMLT-W603.wingroup.windeploy.ntdev.microsoft.com ([157.54.18.6]) with mapi; Mon, 5 Nov 2007 13:35:54 -0800 From: Jakob Lichtenberg To: Christopher L Conway Cc: "caml-list@inria.fr" Date: Mon, 5 Nov 2007 13:35:53 -0800 Subject: RE: [Caml-list] FW: CamlIDL: Returning a whole array of cows Thread-Topic: [Caml-list] FW: CamlIDL: Returning a whole array of cows Thread-Index: Acgf8tA74c0ocZMES1qAU/pFM2QU/gAAGWRg Message-ID: References: <4a051d930711051250j20042a4chac2ce518a6d979e9@mail.gmail.com> <4a051d930711051328k23a34694j3738798857588cea@mail.gmail.com> In-Reply-To: <4a051d930711051328k23a34694j3738798857588cea@mail.gmail.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Miltered: at concorde with ID 472F8CBC.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; camlidl:01 camlidl:01 val:01 val:01 iirc:01 hand-code:01 stub:01 malloc:01 pointer:01 stub:01 stubs:01 mlsize:01 struct:01 struct:01 ctxs:01 Christopher, I probably added to the confusion by providing get_cows_inout in the first = place :-) Let me clarify: I am interested in camlidl exposing the function: val get_cows : unit -> cow array My included get_cows_inout simply demonstrate my current workaround where I= hack the cows API, but the ML code that use get_cows_inout is incredibly u= gly. Thanks, - Jakob -----Original Message----- From: christopherleeconway@gmail.com [mailto:christopherleeconway@gmail.com= ] On Behalf Of Christopher L Conway Sent: Monday, November 05, 2007 1:28 PM To: Jakob Lichtenberg Cc: caml-list@inria.fr Subject: Re: [Caml-list] FW: CamlIDL: Returning a whole array of cows Jakob, Sorry for the confusion: my suggestion was for your get_cows_inout function (where the integer input constrains the length of the output). For get_cows, just use: [size_is(*len)] cow *get_cows([ignore] int* len); Regards, Chris On 11/5/07, Jakob Lichtenberg wrote: > Christopher, > > Thanks for the immediate reply, > > Even if I can change the interface, you suggestion provides an ML API wit= h the wrong ML type: > val get_cows : int -> cow array > > I want a type: > val get_cows : unit -> cow array > > Why: The ML user has no idea how many cows will be returned and can hence= not be expected to provide this as an argument! > > Thanks, > > - Jakob > > -----Original Message----- > From: christopherleeconway@gmail.com [mailto:christopherleeconway@gmail.c= om] On Behalf Of Christopher L Conway > Sent: Monday, November 05, 2007 12:51 PM > To: Jakob Lichtenberg > Cc: caml-list@inria.fr > Subject: Re: [Caml-list] FW: CamlIDL: Returning a whole array of cows > > Jakob, > > I sent out pretty much the same question to the list just last week > and also didn't get a satisfactory answer (see here: > http://caml.inria.fr/pub/ml-archives/caml-list/2007/10/efb73229fa177fb413= e663a2c1ad28b4.en.html). > It seems that when you add a size_is annotation to a parameter, the > size is treated as a pre-condition, not as a post-condition. If you > have the freedom to change the C API, you might try: > > [size_is(*outputlen)] cow *get_cows_inout([in] int inputlen, [ignore] > int *outputlen); > > IIRC, this will give you the correct behavior. The alternative is > hand-code the wrapper. > > Regards, > Chris > > On 11/5/07, Jakob Lichtenberg wrote: > > > > > > > > > > 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= with > > an uninitialized size. > > > > > > > > > > > > 2. Details: > > > > > > > > I am declaring a function 'void get_cows([out] int* len, [length_is(*le= n), > > 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. Ano= ther > > 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 c= ows > > to 'ca', however not more than 'inputlen' elements. Write number of co= ws > > written to '*outputlen'. > > > > > > > > void get_cows(int* len, cow **ca); // Malloc array for cows. Save numb= er 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 follow= ing > > 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= ** > > 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())) > > > > 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(dealloc, "free(*cows);"); > > _______________________________________________ > > Caml-list mailing list. Subscription management: > > http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list > > Archives: http://caml.inria.fr > > Beginner's list: > > http://groups.yahoo.com/group/ocaml_beginners > > Bug reports: http://caml.inria.fr/bin/caml-bugs > > > > > > >