From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 2 Oct 92 15:17:52 GMT From: hfsi!pdennis@uunet.uu.net (WIS Program Group ) Subject: Re: Variant Records from Ada to C Message-ID: <1992Oct2.151752.21818@hfsi.uucp> List-Id: In article 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 > 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