comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Messing with access types...
Date: Mon, 28 Dec 2020 14:56:51 +0100	[thread overview]
Message-ID: <rsco71$8s6$1@gioia.aioe.org> (raw)
In-Reply-To: rscgck$op7$1@dont-email.me

On 2020-12-28 12:43, Marek wrote:
> 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));

You should never convert access types, because to do so, you must first 
learn the accessibility rules. No man can do that while keeping sanity. 
So, just do this:

    return ATA.To_Pointer (F.Data).all'Unchecked_Access;
        -- Mind your business, COMPILER!

> 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 is record
       Id   : Interfaces.C.int; -- If that is int
       Data : System.Address;   -- Could be a named access type [*]
    end record;
    pragma Convention (C, Feature);

>     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;

    type Feature_Array is array (size_t) of aliased Feature; -- Flat
    pragma Convention (C, Feature_Array);
    type Feature_Array_Ptr is access all Feature_Array;
    pragma Convention (C, Feature_Array_Ptr);

    function Get_Me_Features return Feature_Array_Ptr;
    pragma Import (C, Get_Me_features, "???");

That should be all necessary to do this:

    List : Feature_Array renames Get_Me_Features.all;
begin
    for I in size_t'Range loop
       exit when List (I) = Null_Feature;
       declare
          Data : Whatever_C_Type;
          for Data'Address use List (I).Data;
          pragma Import (Ada, Data);
       begin
          ...
       end;
    end loop;

-------------------------------------
* Here is a variant without using addresses

    type Whatever_C_Type is record
       ...
    end record;
    pragma Convention (C, Whatever_C_Type);
    type Whatever_C_Type_Ptr is access all Whatever_C_Type;
    pragma Convention (C, Whatever_C_Type_Ptr);

    type Feature is record
       Id   : Interfaces.C.int;
       Data : Whatever_Ptr;
    end record;
    pragma Convention (C, Feature);
    ...

    for I in size_t'Range loop
       exit when List (I) = Null_Feature;
       declare
          Data : Whatever_C_Type renames List (I).Data.all;
       begin
          ...
       end;
    end loop;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

  reply	other threads:[~2020-12-28 13:56 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
2020-12-28 13:56     ` Dmitry A. Kazakov [this message]
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