comp.lang.ada
 help / color / mirror / Atom feed
From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: differences between Ada and C in gnat forcing me to use C instead of Ada
Date: Mon, 25 Mar 2019 19:38:12 +0200
Date: 2019-03-25T19:38:12+02:00	[thread overview]
Message-ID: <gfsi05F491iU1@mid.individual.net> (raw)
In-Reply-To: <2afba838-16fd-4d5b-906a-b9cd1d864ce6@googlegroups.com>

On 19-03-25 16:09 , matthewbrentmccarty@gmail.com wrote:
> Hi all:
    ...
> For some reason when I call sane_get_devices as in:
>
>       type Sane_Device_Ptr is access all sane_sane_h.SANE_Device;
>       for Sane_Device_Ptr'Size use Standard'Address_Size;
>       pragma Convention (C, Sane_Device_Ptr);
>
>       type Device_Array is array (Integer range <>) of aliased Sane_Device_Ptr;
>       pragma Convention (C, Device_Array);
>       ...
>       devices :  aliased  Device_Array (1..5);
>       Status := sane_sane_h.sane_get_devices (devices(1)'Address, sane_sane_h.SANE_Bool(SANE_TRUE));

I think the Ada profile of sane_get_devices, above, is wrong. See below.

> I get back garbage but in C, it works.

Later, on 19-03-25 18:42 , matthewbrentmccarty@gmail.com wrote:
 > Hi all:
    ...
 > In my C example which works, I have a header that says:
 >
 > #define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))
 > void sane_print_devices (const SANE_Device ** device_list);
 >
 >
 > and then C code which does the following:
 >
 > const SANE_Device	**device_list;
 >
 > status = sane_get_devices (&device_list, SANE_TRUE);

which agrees with the profile for sane_get_devices quoted later in that 
message:

 >     SANE_Status sane_get_devices (const SANE_Device *** device_list,
 >                                   SANE_Bool local_only);

In that profile, the device_list parameter is a pointer to a pointer to 
a pointer to a device_list (three *'s). The Ada code has only two 
pointer levels, so a conflict.

 From the description of sane_get_devices, also quoted in that message:

 > If the function executes successfully, it stores a pointer to
 > a NULL terminated array of pointers to SANE_Device structures
 > in *device_list.

This shows that the device_list is logically an "out" parameter, that 
the value returned is a pointer to an array of pointers to device 
records, and that the responsibility for allocating the array  of 
pointers to the device records (as well as the device records 
themselves) lies with the SANE library, not with the client.

This also answers Dmitry's question on how the client knows the number 
of devices returned: the array (to which a pointer is returned) has a 
null pointer at its end.

The Ada code should be something like this (not compiled nor tested, 
with representations omitted):

    type Sane_Device_Ptr is access all sane_sane_h.SANE_Device;

    type Device_Array is array (Integer range 1 .. 500)
       of aliased Sane_Device_Ptr;
    -- Constrained so as to avoid any problems with bounds dope.
    -- The actual array constructed in sane_get_devices may be shorter
    -- or longer.
    -- If there are less than 500 devices, the actual array ends with
    -- a null pointer at some index <= 500.
    -- If there are over 500 devices, the terminating null pointer will
    -- not be present.

    type Device_Array_Ptr is access all Device_Array;
    ...
    devices :  Device_Array_Ptr;

    Status := sane_sane_h.sane_get_devices (
       device_list => Device_Array_Ptr,
       local_only  => sane_sane_h.SANE_Bool(SANE_TRUE));

Here I have assumed that the device_list parameter is declared in the 
Ada profile of sane_get_devices as "out Device_Array_Ptr", which (with 
the C convention) provides pass by reference (and gives the third level 
of pointers).

HTH...

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


  parent reply	other threads:[~2019-03-25 17:38 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-25  5:46 differences between Ada and C in gnat forcing me to use C instead of Ada matthewbrentmccarty
2019-03-25  5:58 ` Jere
2019-03-25  8:25 ` Dmitry A. Kazakov
2019-03-25 14:06   ` Florian Weimer
2019-03-25 10:56 ` Philip Munts
2019-03-25 11:54 ` Lucretia
2019-03-25 14:09 ` matthewbrentmccarty
2019-03-25 14:20   ` Dmitry A. Kazakov
2019-03-25 16:46     ` Jeffrey R. Carter
2019-03-25 18:01       ` Dmitry A. Kazakov
2019-03-25 17:38   ` Niklas Holsti [this message]
2019-03-25 16:42 ` matthewbrentmccarty
2019-03-25 18:18   ` Dmitry A. Kazakov
2019-04-04  0:51     ` matthewbrentmccarty
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox