* Variant Records from Ada to C
@ 1992-10-01 14:23 Randy Torres
0 siblings, 0 replies; 3+ messages in thread
From: Randy Torres @ 1992-10-01 14:23 UTC (permalink / raw)
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Variant Records from Ada to C
@ 1992-10-02 15:17 WIS Program Group
0 siblings, 0 replies; 3+ messages in thread
From: WIS Program Group @ 1992-10-02 15:17 UTC (permalink / raw)
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Variant Records from Ada to C
@ 1992-10-02 19:01 agate!spool.mu.edu!sdd.hp.com!caen!deccrl!news.crl.dec.com!pa.dec.com!dat
0 siblings, 0 replies; 3+ messages in thread
From: agate!spool.mu.edu!sdd.hp.com!caen!deccrl!news.crl.dec.com!pa.dec.com!dat @ 1992-10-02 19:01 UTC (permalink / raw)
In reply to Randy's post of Sharon's question we'll have to look at
several issues.
Issues:
1) From the given code (following) the mapping of data from
the Ada record xrec to the C structure xrec will *NOT WORK*.
The interface to the void function pass_string_array *WILL
NOT* work either due to the passing of a non-ASCII.NUL terminated
string to the C function (printf will bomb even if it makes it
past the call interface).
The reasons why the void function pass_record will not work are:
a) The order and types of data will not overlay properly.
b) pragma INTERFACE does not provide a data space mapping
it only maps entry points (and based on vendor, only hints to
calling standards).
2) pragma INTERFACE is implementation dependent. For VAX Ada
there are additional pragmas for IMPORT_PROCEDURE,
IMPORT_VALUED_PROCEDURE et.al. So while the following Ada
is valid it is highly dependent on the implementation of the
Ada and C compilers for that host if the interface will map
at all. We'll ignore cross-host here (that in and of itself
is a subject for another posting).
3) The data storage issues between the Ada and C compiler are the
most germane to this posting. Note the additional data objects
in the C structure xrec. There are no corresponding objects in the
Ada record for things like unsigned s2_offset, dv1, dv2, etc.
After fixing the data object issues between the C structure and
Ada record (variant or not) I would STRONGLY recommend that
the pragma PACK be used for the Ada data structure. While some
may argue that it may not be necessary here I would would rather
be safe than sorry.
Also in the C program I would take great care to be very specific
on the exact matching of data types to memory allocation. The
pragma INTERFACE *DOES NOT* guarantee data alignment nor data
passing standard (r-value versus l-value, etc.).
Richard Wallace
Digital Equipment Corporation
301 Rockrimmon Blvd. South
CXO2-1/7A
Colorado Springs, CO 80919-2398
(719)548-2792
<wallace@cookie.enet.dec.com>
"The opinions expressed are my own, Uncle Bob
may, or may not, agree with me."
<<<<original code>>>>
: 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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~1992-10-02 19:01 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1992-10-01 14:23 Variant Records from Ada to C Randy Torres
-- strict thread matches above, loose matches on Subject: below --
1992-10-02 15:17 WIS Program Group
1992-10-02 19:01 agate!spool.mu.edu!sdd.hp.com!caen!deccrl!news.crl.dec.com!pa.dec.com!dat
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox