From: dhenry <tfc.duke@gmail.com>
Subject: Ada to C interfacing with access on unconstrained array
Date: Tue, 20 Oct 2009 06:07:18 -0700 (PDT)
Date: 2009-10-20T06:07:18-07:00 [thread overview]
Message-ID: <2ec52d54-31f6-4289-9a9a-d947be65758c@o21g2000vbl.googlegroups.com> (raw)
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.
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.
next reply other threads:[~2009-10-20 13:07 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-20 13:07 dhenry [this message]
2009-10-20 16:11 ` Ada to C interfacing with access on unconstrained array 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
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