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.5 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE, SPF_SOFTFAIL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr 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 614B8BC6B for ; Mon, 5 Nov 2007 22:20:40 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAN8XL0fAXQImh2dsb2JhbACOegEBAQgKKYEP X-IronPort-AV: E=Sophos;i="4.21,374,1188770400"; d="scan'208";a="18967328" Received: from discorde.inria.fr ([192.93.2.38]) by mail4-smtp-sop.national.inria.fr with ESMTP; 05 Nov 2007 22:20:40 +0100 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id lA5LKNxQ027651 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Mon, 5 Nov 2007 22:20:39 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAN8XL0eDa3PWn2dsb2JhbACOegEBAQEHBAYJCBiBDw X-IronPort-AV: E=Sophos;i="4.21,374,1188770400"; d="scan'208";a="18967325" Received: from smtp.microsoft.com ([131.107.115.214]) by mail4-smtp-sop.national.inria.fr with ESMTP; 05 Nov 2007 22:20:38 +0100 Received: from tk1-exhub-c103.redmond.corp.microsoft.com (157.56.116.114) 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:20:23 -0800 Received: from TK5-EXMLT-W603.wingroup.windeploy.ntdev.microsoft.com (157.54.18.6) 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 13:20:32 -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:20:32 -0800 From: Jakob Lichtenberg To: Christopher L Conway Cc: "caml-list@inria.fr" Date: Mon, 5 Nov 2007 13:20:31 -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: Acgf7Yu2gSceYO0hQg65hJVLIwXSsgAA9sBg Message-ID: References: <4a051d930711051250j20042a4chac2ce518a6d979e9@mail.gmail.com> In-Reply-To: <4a051d930711051250j20042a4chac2ce518a6d979e9@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 discorde with ID 472F8917.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; camlidl:01 val:01 val:01 camlidl: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, Thanks for the immediate reply, Even if I can change the interface, you suggestion provides an ML API with = 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 n= ot be expected to provide this as an argument! Thanks, - Jakob -----Original Message----- From: christopherleeconway@gmail.com [mailto:christopherleeconway@gmail.com= ] 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/efb73229fa177fb413e6= 63a2c1ad28b4.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 w= ith > 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 co= ws. > (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. Anoth= er > 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 cow= s > 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 followin= g > 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 > >