From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,f0256820d7b60c30 X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII Path: g2news2.google.com!postnews.google.com!h14g2000pri.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Ada to C interfacing with access on unconstrained array Date: Tue, 20 Oct 2009 09:24:24 -0700 (PDT) Organization: http://groups.google.com Message-ID: <68717f95-87be-4f6b-9c63-5cd4f6b04b0d@h14g2000pri.googlegroups.com> References: <2ec52d54-31f6-4289-9a9a-d947be65758c@o21g2000vbl.googlegroups.com> NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1256055864 3549 127.0.0.1 (20 Oct 2009 16:24:24 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Tue, 20 Oct 2009 16:24:24 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: h14g2000pri.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618),gzip(gfe),gzip(gfe) Xref: g2news2.google.com comp.lang.ada:8747 Date: 2009-10-20T09:24:24-07:00 List-Id: On Oct 20, 6:07=A0am, dhenry 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 > > =A0 =A0type Nut_Type is > =A0 =A0 =A0 record > =A0 =A0 =A0 =A0 =A0Diameter : Integer; > =A0 =A0 =A0 =A0 =A0Weight =A0 : Integer; > =A0 =A0 =A0 =A0 =A0Age =A0 =A0 =A0: Integer; > =A0 =A0 =A0 end record; > > =A0 =A0type Nut_Array_Type is array (Positive range <>) of Nut_Type; > =A0 =A0type Nut_Array_Access is access Nut_Array_Type; > > =A0 =A0type Coco_Type is > =A0 =A0 =A0 record > =A0 =A0 =A0 =A0 =A0X =A0 =A0: Integer; > =A0 =A0 =A0 =A0 =A0Y =A0 =A0: Integer; > =A0 =A0 =A0 =A0 =A0Nuts : Nut_Array_Access; > =A0 =A0 =A0 end record; > > =A0 =A0-- This is the procedure I want to be executed from C > =A0 =A0procedure Climb (Coco : in Coco_Type); > > end Foo; > -------------------------------------------------- > package body Foo is > > =A0 =A0procedure Climb (Coco : in Coco_Type) is > =A0 =A0begin > =A0 =A0 =A0 -- Climb on the coco... > =A0 =A0end 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" =3D> C_Climb =3D> 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 > > =A0 =A0type C_Nut_Type is > =A0 =A0 =A0 record > =A0 =A0 =A0 =A0 =A0Diameter : Interfaces.C.int; > =A0 =A0 =A0 =A0 =A0Weight =A0 : Interfaces.C.int; > =A0 =A0 =A0 =A0 =A0Age =A0 =A0 =A0: Interfaces.C.int; > =A0 =A0 =A0 end record; > > =A0 =A0type C_Nut_Array is array (Interfaces.C.int range <>) of aliased > C_Nut_Type; > =A0 =A0type C_Nut_Array_Access is access all C_Nut_Array; > > =A0 =A0package C_Nut_Pointers is > =A0 =A0 =A0 new Interfaces.C.Pointers (Interfaces.C.int, C_Nut_Type, > C_Nut_Array, (0, 0, 0)); > > =A0 =A0procedure Climb_C (C_X =A0 =A0: in Interfaces.C.int; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 C_Y =A0 =A0: in Interfaces.C.= int; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 C_Nuts : in C_Nut_Pointers.Po= inter; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 C_Len =A0: in Interfaces.C.in= t); > > =A0 =A0pragma Export (C, Climb_C, "climb"); > > end Foo.C_Interface; > -------------------------------------------------- > package body Foo.C_Interface is > > =A0 =A0procedure Climb_C (C_X =A0 =A0: in Interfaces.C.int; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 C_Y =A0 =A0: in Interfaces.C.= int; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 C_Nuts : in C_Nut_Pointers.Po= inter; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 C_Len =A0: in Interfaces.C.in= t) is > > =A0 =A0 =A0 subtype My_Nuts is C_Nut_Array (1 .. C_Len); > =A0 =A0 =A0 type My_Nuts_Access is access all My_Nuts; > > =A0 =A0 =A0 Nuts : aliased My_Nuts; > =A0 =A0 =A0 for Nuts'Address use C_Nuts.all'Address; > > =A0 =A0 =A0 Nuts_Ptr : My_Nuts_Access :=3D Nuts'Unchecked_Access; > > =A0 =A0 =A0 Coco : Coco_Type; > =A0 =A0begin > =A0 =A0 =A0 Coco.X =A0 =A0:=3D Integer (C_X); > =A0 =A0 =A0 Coco.Y =A0 =A0:=3D Integer (C_Y); > > =A0 =A0 =A0 -- How do I connect this access with my C pointer C_Nuts? > =A0 =A0 =A0 Coco.Nuts :=3D Nuts_Ptr; -- FAIL because My_Nuts_Access is no= t an > Nut_Array_Access > > =A0 =A0 =A0 Climb (Coco); > =A0 =A0end 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 :=3D new Nut_Array_Type (1 .. Integer > (C_Len)); > > So I can write "Coco.Nuts :=3D 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.