comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: Ada to C interfacing with access on unconstrained array
Date: Tue, 20 Oct 2009 09:24:24 -0700 (PDT)
Date: 2009-10-20T09:24:24-07:00	[thread overview]
Message-ID: <68717f95-87be-4f6b-9c63-5cd4f6b04b0d@h14g2000pri.googlegroups.com> (raw)
In-Reply-To: 2ec52d54-31f6-4289-9a9a-d947be65758c@o21g2000vbl.googlegroups.com

On Oct 20, 6:07 am, dhenry <tfc.d...@gmail.com> wrote:
> Hello,
>
> I am trying to interface C with Ada: I want to call an Ada procedure
> from C.
> The Ada procedure takes as parameter a record, containing some
> integers and
> fat access types ("access all").
>
> Ideally, I'd like to have no copy during the interfacing between Ada
> and C.

David,

Unfortunately, I don't think there's a solution.  The reason is that
on some implementations, the Nut_Array_Access, which is an access to
an unconstrained array, is implemented by making sure that a vector
containing the bounds is adjacent to the array data, and having the
access type be the address of the array data or perhaps the address of
the bounds, or something like that.  That means that if you have an
area of memory consisting just of data array, with no bound vector
adjacent to it, you can't convert the location to an access-to-
unconstrained-array type without copying the data.

                                            -- Adam


> Here is the Ada code:
>
> --------------------------------------------------
> package Foo is
>
>    type Nut_Type is
>       record
>          Diameter : Integer;
>          Weight   : Integer;
>          Age      : Integer;
>       end record;
>
>    type Nut_Array_Type is array (Positive range <>) of Nut_Type;
>    type Nut_Array_Access is access Nut_Array_Type;
>
>    type Coco_Type is
>       record
>          X    : Integer;
>          Y    : Integer;
>          Nuts : Nut_Array_Access;
>       end record;
>
>    -- This is the procedure I want to be executed from C
>    procedure Climb (Coco : in Coco_Type);
>
> end Foo;
> --------------------------------------------------
> package body Foo is
>
>    procedure Climb (Coco : in Coco_Type) is
>    begin
>       -- Climb on the coco...
>    end Climb;
>
> end Foo;
> --------------------------------------------------
>
> I want to use the Climb procedure. For interfacing, I can create an
> intermediate
> procedure C_Climb that fits well with C, but the Climb procedure can't
> be changed.
>
> The C_Climb procedure will take some data from C, and rebuild a
> Coco_Type object
> to give to the Climb procedure: "C program" => C_Climb => Climb.
>
> My main problem is the Coco_Type.Nuts component, which is an access to
> an
> unconstrained array. I can't find how to map it without allocation/
> copy data.
>
> Here is an attempt to implement C_Climb:
>
> --------------------------------------------------
> with Interfaces.C;
> with Interfaces.C.Pointers;
>
> package Foo.C_Interface is
>
>    type C_Nut_Type is
>       record
>          Diameter : Interfaces.C.int;
>          Weight   : Interfaces.C.int;
>          Age      : Interfaces.C.int;
>       end record;
>
>    type C_Nut_Array is array (Interfaces.C.int range <>) of aliased
> C_Nut_Type;
>    type C_Nut_Array_Access is access all C_Nut_Array;
>
>    package C_Nut_Pointers is
>       new Interfaces.C.Pointers (Interfaces.C.int, C_Nut_Type,
> C_Nut_Array, (0, 0, 0));
>
>    procedure Climb_C (C_X    : in Interfaces.C.int;
>                       C_Y    : in Interfaces.C.int;
>                       C_Nuts : in C_Nut_Pointers.Pointer;
>                       C_Len  : in Interfaces.C.int);
>
>    pragma Export (C, Climb_C, "climb");
>
> end Foo.C_Interface;
> --------------------------------------------------
> package body Foo.C_Interface is
>
>    procedure Climb_C (C_X    : in Interfaces.C.int;
>                       C_Y    : in Interfaces.C.int;
>                       C_Nuts : in C_Nut_Pointers.Pointer;
>                       C_Len  : in Interfaces.C.int) is
>
>       subtype My_Nuts is C_Nut_Array (1 .. C_Len);
>       type My_Nuts_Access is access all My_Nuts;
>
>       Nuts : aliased My_Nuts;
>       for Nuts'Address use C_Nuts.all'Address;
>
>       Nuts_Ptr : My_Nuts_Access := Nuts'Unchecked_Access;
>
>       Coco : Coco_Type;
>    begin
>       Coco.X    := Integer (C_X);
>       Coco.Y    := Integer (C_Y);
>
>       -- How do I connect this access with my C pointer C_Nuts?
>       Coco.Nuts := Nuts_Ptr; -- FAIL because My_Nuts_Access is not an
> Nut_Array_Access
>
>       Climb (Coco);
>    end Climb_C;
>
> end Foo.C_Interface;
> --------------------------------------------------
>
> Currently, the only way I found is to declare a Nut_Array_Access and
> allocate memory with new:
>
> Nuts_Ptr : Nut_Array_Access := new Nut_Array_Type (1 .. Integer
> (C_Len));
>
> So I can write "Coco.Nuts := Nuts_Access;". But I must fill
> Nuts_Access.all with C_Nuts' data, and
> that's what I'd like to avoid.
>
> Any idea on the interfacing is welcome.
>
> Yours,
> David.




  parent reply	other threads:[~2009-10-20 16:24 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-20 13:07 Ada to C interfacing with access on unconstrained array dhenry
2009-10-20 16:11 ` Dmitry A. Kazakov
2009-10-21  9:25   ` dhenry
2009-10-21 12:09     ` Dmitry A. Kazakov
2009-10-21 12:14       ` Dmitry A. Kazakov
2009-10-20 16:24 ` Adam Beneschan [this message]
2009-10-20 18:40 ` tmoran
2009-10-21  3:29   ` John B. Matthews
2009-10-21  9:29     ` dhenry
2009-10-21 14:16       ` John B. Matthews
replies disabled

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