From: Jakob Lichtenberg <jakobl@windows.microsoft.com>
To: Christopher L Conway <cconway@cs.nyu.edu>
Cc: "caml-list@inria.fr" <caml-list@inria.fr>
Subject: RE: [Caml-list] FW: CamlIDL: Returning a whole array of cows
Date: Mon, 5 Nov 2007 13:20:31 -0800 [thread overview]
Message-ID: <DACB514F44E4864CAFDC7DAD144A7E6CBC1FB2A22E@NA-EXMSG-W601.wingroup.windeploy.ntdev.microsoft.com> (raw)
In-Reply-To: <4a051d930711051250j20042a4chac2ce518a6d979e9@mail.gmail.com>
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 <jakobl@windows.microsoft.com> 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
>
>
next prev parent reply other threads:[~2007-11-05 21:20 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-05 18:31 Jakob Lichtenberg
2007-11-05 20:50 ` [Caml-list] " Christopher L Conway
2007-11-05 21:20 ` Jakob Lichtenberg [this message]
2007-11-05 21:28 ` Christopher L Conway
2007-11-05 21:35 ` Jakob Lichtenberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DACB514F44E4864CAFDC7DAD144A7E6CBC1FB2A22E@NA-EXMSG-W601.wingroup.windeploy.ntdev.microsoft.com \
--to=jakobl@windows.microsoft.com \
--cc=caml-list@inria.fr \
--cc=cconway@cs.nyu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox