comp.lang.ada
 help / color / mirror / Atom feed
From: Marek <ficorax@gmail.com>
Subject: Re: Messing with access types...
Date: Mon, 28 Dec 2020 12:43:15 +0100	[thread overview]
Message-ID: <rscgck$op7$1@dont-email.me> (raw)
In-Reply-To: <rscb6f$1rdr$1@gioia.aioe.org>

On 28.12.2020 11:14, Dmitry A. Kazakov wrote:
> 
> What are you trying to achieve? Because the code does not make much
> sense to me.
> 
> P.S. If you are trying to do some C bindings flat arrays are easier
> choice than Interfaces.C.Pointers. C has no arrays, but pointers. Ada's
> arrays are never compatible with any pointers, except when flat.
> Therefore using access to String would be wrong in most, if not all, cases.
> 

Code is a fragment some plugin framework for host written in C. When
plugin is initialized it receives pointer to host features. Then I can
scan them to find concrete feature (Id) and retrieve data.
Problem is with instantiation generic function Get_Data, more precisely
in line:

   return T_Access (ATA.To_Pointer (F.Data));

OK, some changes to code to clear view:

with System;

package Util is

   type Feature is record
      Id  : Integer;
      Data : System.Address;
   end record;

   type Feature_Access is access all Feature;

   Null_Feature : constant Feature := (0, System.Null_Address);

   type Feature_Array is array (Natural range <>) of aliased Feature;

   generic
      type T is private;
      type T_Access is access all T;
   function Get_Data (H : access Feature; Id : Integer) return T_Access;

   generic
      type T is private;
      type T_Access is access all T;
   function Get_Query
     (H        : access Feature; Id : Integer; Data : in out T_Access;
      Required : Boolean) return Integer;

end Util;

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

pragma Ada_2012;

with Interfaces.C.Pointers;

with System.Address_To_Access_Conversions;

package body Util is

   package Ptr is new Interfaces.C.Pointers
     (Index              => Natural,
      Element            => Feature,
      Element_Array      => Feature_Array,
      Default_Terminator => Null_Feature);

   use Ptr;

   --------------
   -- Get_Data --
   --------------

   function Get_Data (H : access Feature; Id : Integer) return T_Access
   is
      Pointer : Ptr.Pointer := Ptr.Pointer (H);

      package ATA is new System.Address_To_Access_Conversions (T);

   begin
      if H /= null then
         loop
            declare
               F : access Feature := Pointer;
            begin
               if Id = F.Id then
                  return T_Access (ATA.To_Pointer (F.Data));
               end if;
            end;

            Ptr.Increment (Pointer);

            exit when Pointer = null;

         end loop;
      end if;

      return null;
   end Get_Data;

   ---------------
   -- Get_Query --
   ---------------

   function Get_Query
     (H        : access Feature; Id : Integer; Data : in out T_Access;
      Required : Boolean) return Integer
   is
      function Get is new Get_Data (T, T_Access);
   begin

      Data := Get (H, Id);

      if Required and (Data /= null) then
         return Id;
      end if;

      return 0;
   end Get_Query;

end Util;

  reply	other threads:[~2020-12-28 11:43 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-28  9:44 Messing with access types Marek
2020-12-28 10:14 ` Dmitry A. Kazakov
2020-12-28 11:43   ` Marek [this message]
2020-12-28 13:56     ` Dmitry A. Kazakov
2020-12-28 18:56       ` Marek
2020-12-28 19:53         ` Dmitry A. Kazakov
replies disabled

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