comp.lang.ada
 help / color / mirror / Atom feed
From: matthewbrentmccarty@gmail.com
Subject: Re: differences between Ada and C in gnat forcing me to use C instead of Ada
Date: Wed, 3 Apr 2019 17:51:43 -0700 (PDT)
Date: 2019-04-03T17:51:43-07:00	[thread overview]
Message-ID: <e53a08a6-8b8b-4f10-a7e3-270c1e5e34f0@googlegroups.com> (raw)
In-Reply-To: <q7b622$1lif$1@gioia.aioe.org>

Hi all:

OK!  I was looking at this again with fresh eyes and with a little tweaking, I got Dmitry's example working with the following code:



with Text_Io; use Text_io;
with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;

procedure foo3 is

   subtype SANE_Word is int;  -- /usr/include/sane/sane.h:43
   subtype SANE_Bool is SANE_Word;  -- /usr/include/sane/sane.h:44

   type SANE_Status is
     (SANE_STATUS_GOOD,
      SANE_STATUS_UNSUPPORTED,
      SANE_STATUS_CANCELLED,
      SANE_STATUS_DEVICE_BUSY,
      SANE_STATUS_INVAL,
      SANE_STATUS_EOF,
      SANE_STATUS_JAMMED,
      SANE_STATUS_NO_DOCS,
      SANE_STATUS_COVER_OPEN,
      SANE_STATUS_IO_ERROR,
      SANE_STATUS_NO_MEM,
      SANE_STATUS_ACCESS_DENIED);
   pragma Convention (C, SANE_Status);  -- /usr/include/sane/sane.h:71

   subtype SANE_Char is char;  -- /usr/include/sane/sane.h:46
   subtype SANE_Int is SANE_Word;  -- /usr/include/sane/sane.h:45
   type SANE_String_Const is access all SANE_Char;  -- /usr/include/sane/sane.h:48

   type SANE_Auth_Callback is access procedure
        (arg1 : SANE_String_Const;
         arg2 : access SANE_Char;
         arg3 : access SANE_Char);
   pragma Convention (C, SANE_Auth_Callback);  -- /usr/include/sane/sane.h:214

    type SANE_Device is record
      name   : chars_ptr;
      vendor : chars_ptr;
      model  : chars_ptr;
      c_type : chars_ptr;
    end record;
    pragma Convention (C, SANE_Device);
    type SANE_Device_Ptr is access all SANE_Device;
    pragma Convention (C, SANE_Device_Ptr);

       -- Flat array of devices
    type SANE_Device_Array is array (size_t) of SANE_Device_Ptr;
    pragma Convention (C, SANE_Device_Array);
    type SANE_Device_Array_Ptr is access all SANE_Device_Array;
    pragma Convention (C, SANE_Device_Array_Ptr);

    function sane_get_devices
             (  device_list :  in out  SANE_Device_Array_Ptr;
                local_only  : SANE_Bool
             )  return SANE_Status;
   pragma Import (C, sane_get_devices, "sane_get_devices");

   function sane_init (version_code : access SANE_Int; authorize : SANE_Auth_Callback) return SANE_Status;  -- /usr/include/sane/sane.h:218
   pragma Import (C, sane_init, "sane_init");

   procedure sane_exit;  -- /usr/include/sane/sane.h:220
   pragma Import (C, sane_exit, "sane_exit");

---------------------------------

   List_Ptr : SANE_Device_Array_Ptr;
   stat : SANE_Status := SANE_STATUS_GOOD;
   version_code : access SANE_Int :=  new SANE_Int;


begin
    stat := sane_init(version_code, null);

    stat := sane_get_devices (List_Ptr, 0);
    declare
       List : SANE_Device_Array renames List_Ptr.all;
    begin
       for Index in List'Range loop      -- "Infinite" loop
          exit when List (Index) = null; -- Null-terminated
         Text_Io.Put_Line ("Name: " & Value (List (Index).name));
         Text_Io.Put_Line ("Vendor: " & Value (List (Index).vendor));
         Text_Io.Put_Line ("Model: " & Value (List (Index).model));
         Text_Io.Put_Line ("C_Type: " & Value (List (Index).c_type));
         
       end loop;
   end;

   sane_exit;
end Foo3;


Now, if I knew that it was possible to interface to C using "sane_get_devices" with a parameter of "device_list :  in out  SANE_Device_Array_Ptr;" instead of the generated "System.Address" parameter, then I would have been delighted to use that method instead of the generated version from "%g++ -c -fdump-ada-spec-slim".  For some reason, I thought the generated version was more accurate.  But I much rather use the SANE_Device_Array_Ptr version since it more accurately matches the documented API calls as explained in the manual.  I had to remove the "not null" on the parameter since it was causing "raised CONSTRAINT_ERROR : foo3.adb:74 access check failed" and it is null when you first call it.  And I still get garbage when passing the 'Address of the first element of my array in my version of the code.  Thanks for the assistance!

Regards,
Matthew McCarty

      reply	other threads:[~2019-04-04  0:51 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
2019-03-25 16:42 ` matthewbrentmccarty
2019-03-25 18:18   ` Dmitry A. Kazakov
2019-04-04  0:51     ` matthewbrentmccarty [this message]
replies disabled

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