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.0 required=5.0 tests=AWL,SPF_NEUTRAL 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 7B7BFBC6B for ; Mon, 5 Nov 2007 22:28:23 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAACYaL0fAXQImh2dsb2JhbACOegEBAQgKKYEP X-IronPort-AV: E=Sophos;i="4.21,374,1188770400"; d="scan'208";a="4076548" Received: from discorde.inria.fr ([192.93.2.38]) by mail1-smtp-roc.national.inria.fr with ESMTP; 05 Nov 2007 22:28:23 +0100 Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id lA5LSMgW027824 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Mon, 5 Nov 2007 22:28:23 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAHIZL0dA6ba6i2dsb2JhbACOegEBAQgEBBMRBYER X-IronPort-AV: E=Sophos;i="4.21,374,1188770400"; d="scan'208";a="5481486" Received: from nf-out-0910.google.com ([64.233.182.186]) by mail3-smtp-sop.national.inria.fr with ESMTP; 05 Nov 2007 22:28:22 +0100 Received: by nf-out-0910.google.com with SMTP id g13so1311088nfb for ; Mon, 05 Nov 2007 13:28:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:sender:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references:x-google-sender-auth; bh=X1aimPf+b7fzlpN2B8DKW9g2wmpnp1Pnw7LqIX2pRfM=; b=j7sP4iwkVa2FhmUiSgXh7jMOSEqFmK0BXZtwPDMkdHNvzwhRwS0FrUQYLMxWLF9rFBV9nSOAE/ktjCrQ0W7NjDM6lNEanPg9rSD8tef11XISqD0tdusnSmFneNBvIXSznEP1B1gTcqe6heahPpVs1/Z5TQ+oL2RF4kBRIdxH8Tw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:sender:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references:x-google-sender-auth; b=ZxcoFCVvSz3R37biVb3hj8WmLNJyz0qshGsASD1IcfvUHnKhDdUmelOX90EHk2ILuxPMwje5IWXRaj2TyQC80whzLKw8rqHki2HLp/hUMEC7p2wsouPG1u/G0Oc8X2TKnR2/FBPq+0As+S4n3JV9WySj/0A+U/RVYtquhqTo+KQ= Received: by 10.78.138.6 with SMTP id l6mr4206427hud.1194298100948; Mon, 05 Nov 2007 13:28:20 -0800 (PST) Received: by 10.78.157.16 with HTTP; Mon, 5 Nov 2007 13:28:20 -0800 (PST) Message-ID: <4a051d930711051328k23a34694j3738798857588cea@mail.gmail.com> Date: Mon, 5 Nov 2007 17:28:20 -0400 From: "Christopher L Conway" Sender: christopherleeconway@gmail.com To: "Jakob Lichtenberg" Subject: Re: [Caml-list] FW: CamlIDL: Returning a whole array of cows Cc: "caml-list@inria.fr" In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <4a051d930711051250j20042a4chac2ce518a6d979e9@mail.gmail.com> X-Google-Sender-Auth: bd75c8799ed35381 X-Miltered: at discorde with ID 472F8AF6.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 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 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 not 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/efb73229fa177fb413e663a2c1ad28b4.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(*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 = { 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); > > > > Begin_root(_vres) > > > > for (_c2 = 0; _c2 < *len; _c2++) { > > > > _v3 = 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 > > 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: > > > > > > > > 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 = > > > > let cows = > > > > 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 _ = 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 > > > > > > >