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: 103376,d9e66bfe9beb10b9 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news2.google.com!proxad.net!newsfeed1.ip.tiscali.net!tiscali!transit1.news.tiscali.nl!dreader2.news.tiscali.nl!not-for-mail Newsgroups: comp.lang.ada Subject: Re: C array to ada record interface References: <404ee0af.0407141517.30cacac7@posting.google.com> <404ee0af.0407221002.1cfdc21e@posting.google.com> From: Ludovic Brenta Date: Sat, 24 Jul 2004 20:48:34 +0200 Message-ID: <87iscdi6m5.fsf@insalien.org> User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) Cancel-Lock: sha1:yYTYXXUlBR6Amq/RGKNpcQGLLko= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Organization: Tiscali bv NNTP-Posting-Date: 24 Jul 2004 20:47:55 CEST NNTP-Posting-Host: 83.134.242.50 X-Trace: 1090694875 dreader2.news.tiscali.nl 62368 83.134.242.50:32838 X-Complaints-To: abuse@tiscali.nl Xref: g2news1.google.com comp.lang.ada:2375 Date: 2004-07-24T20:47:55+02:00 List-Id: (Francisco Javier Loma Daza) writes: > Jeffrey Carter wrote in message Francisco Javier Loma Daza wrote: >> >> > struct >> > { >> > int a,b,c: >> > int len; >> > struct b* arr; >> > } A; >> > >> > And I would love to interface in Ada with a record with a discriminant >> > >> > type B_array(len: Positive) is record >> > arr: array of B(1..len); >> > end record; >> > >> > type A(len: Positive) is >> > a,b,c: Integer; >> > arr: A(len); >> > end record; >> >> Assuming you meant >> >> Arr : B_Array (Len => Len); >> >> this won't work. What you have from C is a pointer; the actual array may >> not even be contiguous with the struct. You'll have to do something like >> >> type B_Ptr is access all B; >> pragma Convention (C, B_Ptr); >> >> type A_Info is record >> A, B, C : Interfaces.C.Int; >> Len : Interfaces.C.Int; >> Arr : B_Ptr; >> end record; >> pragma Convention (C, A_Info); >> >> You only use these types when talking directly to C. For the rest of >> your application, you use something like the record you presented, and >> have your operations that talk to C convert between the 2. > > > Thanks, I think you understood well > > I would want to use some more ada like array, you suggest to implement > that with accesors functions ... I was just wondering if it can be > done, the Len + Arr part, to be set up as an Ada array ... Yes, it can be done: with Ada.Unchecked_Conversion; function To_Ada_Array (Arr : in B_Ptr; Len : in Interfaces.C.int) return B_Array is subtype Array_With_Known_Length is B_Array (1 .. Len); function To_Ada is new Ada.Unchecked_Conversion (Source => B_Ptr, Target => Array_With_Known_Length); begin -- ... end To_Ada_Array; In the begin/end block you have two possible strategies: return To_Ada (B_Ptr); will return a B_Array where the Arr member has the same address (in memory) as the original C array. If you deallocate the C array, you will get a Constraint_Error if you try to use the Ada array. If you want to avoid this, the other strategy is to return a copy: declare Input : Array_With_Known_Lengh := To_Ada (Arr); Result : B_Array (1 .. Len) := Input; begin return Result; end; The advantage of having a copy is that Result.Arr has a different address than the C array; thus you manage the memory separately for the C and Ada arrays. You can now safely deallocate the C array; the Ada compiler will manage the memory for the Ada array for you, since you declared it on the stack. The disadvantage of this approach is that it requires more memory to run; if the array is very large, it could become a problem. HTH (PS. I have not tried to compile my example code, so there may be errors in it) -- Ludovic Brenta.