From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p791eERb030085 for ; Tue, 9 Aug 2011 03:40:14 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuwBAOqOQE7RVdIpimdsb2JhbABCpyAIFAEBAQoJDQcSBiGBQAEBAQECARICExkBGx4DAQsGBQsNLiIBEQEFARwZIodLoUAKjDGCVYUXO4htAgMGhkAEh1yLJog2hBo8g3o X-IronPort-AV: E=Sophos;i="4.67,340,1309730400"; d="scan'208";a="115324707" Received: from mail-pz0-f41.google.com ([209.85.210.41]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 09 Aug 2011 03:40:08 +0200 Received: by pzk4 with SMTP id 4so4421543pzk.14 for ; Mon, 08 Aug 2011 18:40:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; bh=vesPLs//WAo/UvdDwkkfAP2Cz/bgmh43h1XFEcTBo1s=; b=J652vOcfgPf0tchjAvXStaUcdUC5L4mBfVR0MScLdwTFvZF8IMbE26MPyc5S6driQM BU/7N8sDjBSeIdtCls79lWpYguuTjOVSqUZTUmRHBO/XLVe9+fW2Dfb8gzUziijHgxwq T+dKz39clOixMv1O2EZuqLomZCwgzOQjkm3pg= MIME-Version: 1.0 Received: by 10.142.151.31 with SMTP id y31mr6221727wfd.340.1312854006423; Mon, 08 Aug 2011 18:40:06 -0700 (PDT) Received: by 10.68.43.66 with HTTP; Mon, 8 Aug 2011 18:40:06 -0700 (PDT) In-Reply-To: <20110809113359.c306a95842c0c86ea160025d@mega-nerd.com> References: <20110808131504.d9137220d4b4401cc3450e5a@mega-nerd.com> <20110808035322.GI29083@localhost> <20110808174619.00b76d12a02f2c58c10c0108@mega-nerd.com> <20110808080356.GD29083@localhost> <4E401BC7.5040001@inria.fr> <20110809113359.c306a95842c0c86ea160025d@mega-nerd.com> Date: Mon, 8 Aug 2011 20:40:06 -0500 Message-ID: From: Romain Beauxis To: caml-list@inria.fr Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id p791eERb030085 Subject: Re: [Caml-list] Val_int vs caml_copy_nativeint 2011/8/8 Erik de Castro Lopo : > Xavier Leroy wrote: > >> On 08/08/2011 10:03 AM, Guillaume Yziquel wrote: >> >> > Then I do not see anything wrong if the code snippet you sent. However, >> > when you change Val_int to caml_copy_nativeint, the layout of the tuple >> > is different. [...] So if you keep the same OCaml code when reading >> > the result value, it's no surprise that the pointer is shown in >> > place of the integer you expected. >> >> This is good advice indeed: make sure your Caml type declaration >> matches the data representation that your Caml/C stub implements... >> >> >    /* Package up the result as a tuple. */ >> >    v_response = caml_alloc_tuple (3) ; >> >    Store_field (v_response, 0, Val_int (width)) ; >> >    Store_field (v_response, 1, Val_int (height)) ; >> >    Store_field (v_response, 2, caml_copy_string (code)) ; >> >    CAMLreturn (v_response) ; >> >> Additionally, do make sure that "v_response" is registered with the GC >> (declared with one of the CAMLlocal macros). > > This is strange, it wasn't declared with a CAMLlocal macro and it > was working, but if I do declare it with one the program segfaults > during garbage collection (caml_oldify_local_roots). > > The program is small, so I've included the working version of the > C stub code below. In the Ocaml code I have: > >    external iec16022ecc200 : >        int -> (* size *) >        string -> (* code *) >        (int * int * string) = "caml_iec16022ecc200" > > The C stub code below works. If I change "value v_response" to > "CAMLlocal1 (v_response)" it segfaults. If I use caml_copy_nativeint() > instead of Val_int when I'm preparing the v_response tuple I get what > looks like a pointer instead of the small integer (ie [16, 160] range) > I was expecting. > > Cheers, > Erik > > #include > #include > #include > #include > #include > #include > #include > > #include > #include > #include > > #include > > > typedef union > {       unsigned char * u ; >    signed char * s ; >    char * c ; > } flexi_char_ptr_t ; > > > CAMLprim value > caml_iec16022ecc200 (value v_size, value v_code) > {       unsigned char buffer [2048] ; >        flexi_char_ptr_t code, barcode ; >        int width, height, k ; >        value v_response ; This look odd to me. I always place CAMLParam and CAMLlocal declarations are the very beginning of the code.. Don't know if this matters here but perhaps.. >        CAMLparam2 (v_size, v_code) ; > >        width = height = Int_val (v_size) ; >        code.c = String_val (v_code) ; > >        barcode.u = iec16022ecc200 (&width, &height, NULL, strlen (code.c), code.u, NULL, NULL, NULL) ; > >        if (barcode.u == NULL) >        {       failwith ("iec16022ecc200 failed") ; >                fprintf (stderr, "%s %d: Should never get here.\n", __FILE__, __LINE__) ; >                exit (1) ; >                } ; > >        /* Sanity check the buffer size. */ >        assert (width * height < (int) sizeof (buffer) - 1) ; > >        /* Need to convert the resulting 0x00 and 0x01 byte string to a text >         * string that we can pass back to Ocaml. */ >        for (k = 0 ; k < width * height ; k++) >                buffer [k] = barcode.c [k] ? '1' : '0' ; > >        /* Make sure buffer is string terminated. */ >        buffer [width * height] = 0 ; > >        /* Free the memory allocated by iec16022ecc200(). */ >        free (barcode.u) ; > >        barcode.u = buffer ; > >        /* Package up the result as a tuple. */ >        v_response = caml_alloc_tuple (3) ; > >        Store_field (v_response, 0, Val_int (width)) ; >        Store_field (v_response, 1, Val_int (height)) ; >        Store_field (v_response, 2, caml_copy_string (barcode.c)) ; > >    CAMLreturn (v_response) ; > } /* caml_iec16022ecc200 */ Romain