From: pdennis@hfsi.uucp (WIS Program Group )
Subject: Re: Variant Records from Ada to C
Keywords: Variant Records
Reply-To: pdennis@hfsi.UUCP (WIS Program Group )
Organization: HFSI, McLean VA.
Distribution: comp.lang.ada
Date: Fri, 2 Oct 1992 15:17:52 GMT

In article <rtorres.717949389@mikey> rtorres@convex.com (Randy Torres) writes:
>
>Would the following be safe.  I have a variant record and want to pass
>it to a C routine.  I currently know what the data structures will look
>like when past to C.  However, will this data structure change with
>releases of Ada compilers, as well as different compilers?
>
>
>with system;
>
>procedure a is
>   procedure pass_string_array( str : system.address);
>   pragma interface(c, pass_string_array);
>   procedure pass_record( rec : system.address);
>   pragma interface(c, pass_record);
>   type xrec (p1 : integer; p2: integer) is
>   record
>      b  : integer;
>      s1 : string(1..p1);
>      c  : integer;
>      s2 : string(1..p2);
>      case p1 is
>         when 7 =>
>            fld1 : integer;
>         when others =>
>            fld2 : integer;
>      end case;
>   end record;
>   myrec : xrec(7,8);
>begin
>   myrec.b := 66;
>   myrec.c := 77;
>   myrec.s1 := "AAAAABB";
>   myrec.s2 := "CCCCCDDD";
>   myrec.fld1 := 88;
>   pass_string_array(myrec.s1'address);
>   pass_string_array(myrec.s2'address);
>   pass_record(myrec'address);
>end;
>
>
>C file.
>
>
>#include <stdio.h>
>   typedef struct xrec {      
>      int p1;
>      int p2;
>      int b;
>      unsigned s1_offset;
>      struct {
>         int element_size;    /* s1(1)'size */
>         int lower;           /* s1'first */
>         int upper;           /* s1'last */
>         int total;           /* s1'size */
>      } dv1;
>      int c;
>      unsigned s2_offset;
>      struct {
>         int element_size;    /* s2(1)'size */
>         int lower;           /* s2'first */
>         int upper;           /* s2'last */
>         int total;           /* s2'size */
>      } dv2;
>      union {
>         int fld1;
>         int fld2;
>      } n;
>   } *xrec_t;
>
>void pass_record(xrec_t my)
>{
>   char *s1, *s2;
>   s1 = (char *)&(my->s1_offset);
>   s1 += my->s1_offset;
>   s2 = (char *)&(my->s2_offset);
>   s2 += my->s2_offset;
>   printf("p1 = %d\n",my->p1);
>   printf("p2 = %d\n",my->p2);
>   printf("b = %d\n",my->b);
>   printf("c = %d\n",my->c);
>   printf("fld1 = %d\n", my->n.fld1);
>   printf("s1 = %s\n",s1);   
>   printf("s2 = %s\n",s2);   
>}
>
>void pass_string_array(char *s)
>{
>   printf("s = %s\n",s);   
>}
>
>Sharon Shaw			
>CONVEX Systems Integration and Support		
>

I'll comment on the Ada part of things and suggest a couple of options.
No, I do not think this is a safe thing to try for the following reasons:

1.  Passing myrec.s1'address does not ensure that the address of the
    string itself will be passed.  You may end up with the address of
    the string descriptor or something similar.  It looks as if you
    have taken care of this in the c code, but you must ensure that
    this is the implementation of the string descriptor by the Ada
    compiler.  
 
    Usually I try to declare types that try to look like c declarations
    and then use those types.  One method that I think might work would
    be to pass myrec.s1(my_rec.s1'first)'address.  This would ensure 
    that the address of the first character of the string is passed
    to the called procedure.  In the called procedure you may then want
    to declare something along the lines of s1 *char.  The only thing you
    would then want to do is make sure that you make the string one 
    character longer than required and tack an ascii.nul on the end
    of the string.

2.  Passing myrec'address poses similar problems.  One thing you for 
    sure is that you do not know how the compiler defines the record,
    so some form of a representation specification would be recommended.
    However, I don't think that you will be able to write on for the 
    discriminant, or the two strings within the record (someone with more
    knowledge that I should respond to this part).  

Phil Dennis			pdennis@hfsi.com
HFSI, Wis Program Group, McLean, Va. 22102	(703) 827-3564