comp.lang.ada
 help / color / mirror / Atom feed
* Need help mapping a C struct to Ada
@ 2001-03-21 19:56 (null)
  2001-03-21 21:25 ` tmoran
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: (null) @ 2001-03-21 19:56 UTC (permalink / raw)


I'm trying to call some C functions from my Ada program.  The C function
prototype and data types are basically

  typedef struct {
    some fields...
  } element;

  typedef struct {
	  int      num_elements;
     element  the_elements[0];
  } element_table;

  void foo(size_t         *table_size,
			  element_table  *table);

My question is basically about the element_table structure.  In C
this means basically that element_table.the_elements doesn't have
a fixed size.  It is up to the programmer to figure out how much
memory is needed for the desired number of elements and manual
allocate the memory.

My first try at using element_table in Ada95 looked something like

  type element is record 
     some fields...
  end record;
  pragma Convention(C, element);
 
  type element_array is array (natural range <>) of element;
  pragma Convention(C, element_array);

  type element_table (count: positive) is record
     num_elements:   integer;
     the_elements:   element_array(0..count-1);
  end record;
  pragma Convention(C, element_table);

  procedure foo(table_size:  access size_t;
                table:       access element_table);
  pragma Import(C, foo, "foo");

  
That failed because Ada allocated space in element_table for the
field 'count'.  The C code, knowing nothing about 'count' proceded
to put data that was supposed to go into the field 'the_elements'
into the field 'num_elements'.

My second attempt works with the compiler I'm using, but I don't think
it is correct Ada in general.


  type element_array is array (natural range <>) of element;
  pragma Convention(C, element_array);

  type element_table (num_elements: positive) is record
     the_elements:   element_array(0..count-1);
  end record;
  pragma Convention(C, element_table);
 
In this case I'm just crossing my fingers and hoping that the 
Ada compiler lays out the element_table record the same way the 
C compiler does.

What's the correct way of doing this?  

I think programming should be hopeless, i.e. I shouldn't ever say,
"I _hope_ this works."  My current solution isn't hopeless.  Hopefully
somebody can help me out here.




-- 
=======================================================================
 Life is short.                  | Craig Spannring 
      Bike hard, ski fast.       | cts@internetcds.com
 --------------------------------+------------------------------------



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Need help mapping a C struct to Ada
  2001-03-21 19:56 Need help mapping a C struct to Ada (null)
@ 2001-03-21 21:25 ` tmoran
  2001-03-22 20:53   ` tmoran
  2001-03-21 22:21 ` Jeffrey Carter
  2001-03-30  5:59 ` David Thompson
  2 siblings, 1 reply; 6+ messages in thread
From: tmoran @ 2001-03-21 21:25 UTC (permalink / raw)


>  type element_table (count: positive) is record
>     num_elements:   integer;
>     the_elements:   element_array(0..count-1);
>  end record;
>That failed because Ada allocated space in element_table for the
>field 'count'.  The C code, knowing nothing about 'count' proceded

  An Ada description of the C data structure is

   type element_table (count: Interfaces.C.Int) is record
      the_elements:   element_array(Interfaces.C.Unsigned);
   end record;

There is a single "count", and the number of elements is potentially
very large.  If C routines allocate these objects, they will pass back
pointers, not massive structures, so there's no worry about space, but
it's up to you to do the subscript range checking.  If you actually need
to allocate one of these things in Ada, clearly the
"element_array(Interfaces.C.Unsigned)" is unreasonable, so you will have
to figure out some maximum on the number of elements and do

   Max_Possible_Index:constant Interfaces.C.Int := ???
   type element_table (count: Interfaces.C.Int) is record
      the_elements:   element_array(0 .. Max_Possible_Index);
   end record;

>In this case I'm just crossing my fingers and hoping that the
>Ada compiler lays out the element_table record the same way the
>C compiler does.

  A very last resort.  Think "when the C compiler sees one of these
objects being used, what information does it know?".  It knows the first
part of storage is an int, followed by any number of "element"s.  If the
Ada compiler knows more, such as a value for "num_elements" that could
differ from "count", or a dynamic upper bound for the "element_array",
clearly the Ada compiler will have to store that additional information
someplace, and thus the storage arrangements must necessarily differ.
You must inform the Ada compiler of just what (how little) you know when
you get one of these things from a C call.

  You should also use a representation clause

   for element_table use record
     count at 0 range 0 .. Interfaces.C.Int'size - 1;
     the_elements at Interfaces.C.Int'size/System.Storage_Unit
       range 0 .. (Max_Possible_Index+1)*Interfaces.C.Int'size - 1;
   end record;

That will tell the compiler what you want, tell future program maintainers
what you want, and let the compiler tell you if what it's going to do
differs from what you want.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Need help mapping a C struct to Ada
  2001-03-21 19:56 Need help mapping a C struct to Ada (null)
  2001-03-21 21:25 ` tmoran
@ 2001-03-21 22:21 ` Jeffrey Carter
  2001-03-21 23:12   ` Florian Weimer
  2001-03-30  5:59 ` David Thompson
  2 siblings, 1 reply; 6+ messages in thread
From: Jeffrey Carter @ 2001-03-21 22:21 UTC (permalink / raw)


"(null)" wrote:
> 
> I'm trying to call some C functions from my Ada program.  The C function
> prototype and data types are basically
> 
>   typedef struct {
>     some fields...
>   } element;
> 
>   typedef struct {
>           int      num_elements;
>      element  the_elements[0];

My C isn't very good, but isn't this the same as

   element* the_elements;

since you have to "manually allocate the memory"?

If so, then you should probably use an access type with convention C in
Ada.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Need help mapping a C struct to Ada
  2001-03-21 22:21 ` Jeffrey Carter
@ 2001-03-21 23:12   ` Florian Weimer
  0 siblings, 0 replies; 6+ messages in thread
From: Florian Weimer @ 2001-03-21 23:12 UTC (permalink / raw)


Jeffrey Carter <jeffrey.carter@boeing.com> writes:

> My C isn't very good, but isn't this the same as
> 
>    element* the_elements;
> 
> since you have to "manually allocate the memory"?

No, the memory is allocated "inline", directly following after the
num_elements component.  No indirection.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Need help mapping a C struct to Ada
  2001-03-21 21:25 ` tmoran
@ 2001-03-22 20:53   ` tmoran
  0 siblings, 0 replies; 6+ messages in thread
From: tmoran @ 2001-03-22 20:53 UTC (permalink / raw)


Oops, in
   for element_table use record
     count at 0 range 0 .. Interfaces.C.Int'size - 1;
     the_elements at Interfaces.C.Int'size/System.Storage_Unit
       range 0 .. (Max_Possible_Index+1)*Interfaces.C.Int'size - 1;
   end record;
the range of the_elements should of course be
       range 0 .. (Max_Possible_Index+1)*element'size - 1;



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Need help mapping a C struct to Ada
  2001-03-21 19:56 Need help mapping a C struct to Ada (null)
  2001-03-21 21:25 ` tmoran
  2001-03-21 22:21 ` Jeffrey Carter
@ 2001-03-30  5:59 ` David Thompson
  2 siblings, 0 replies; 6+ messages in thread
From: David Thompson @ 2001-03-30  5:59 UTC (permalink / raw)


(null) <cts@kampong.aedinc.net> wrote :
> I'm trying to call some C functions from my Ada program.  The C function
> prototype and data types are basically
...
>   typedef struct {
>   int      num_elements;
>      /*typedef to struct blah*/ the_elements[0];
>   } element_table;
...
> My question is basically about the element_table structure.  In C
> this means basically that element_table.the_elements doesn't have
> a fixed size.  It is up to the programmer to figure out how much
> memory is needed for the desired number of elements and manual
> allocate the memory.
>
Only in GNU C, the language "not entirely unlike" C
compiled by the gcc C compiler by default, not in
standard C and not in (most?) other C compilers.
The 1989/90 standard requires the array bound to be
(fixed and) strictly positive.  Since C does not require
bounds checking, and implementations rarely do it,
it *almost* always works to declare T foo [1],
malloc(sizeof(S)+ (N-1)*sizeof(T)), and use 0..N-1,
although this is ugly(er).  Since this actually works
on reasonable implementations, the new 1999
standard makes it official but with a new, distinct
syntax, called "flexible array member":
  typedef struct { ... T foo []; /* no bound at all */ } S;
  ptr = malloc(sizeof(S) + N * sizeof(T));

--
- David.Thompson 1 now at worldnet.att.net








^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-03-30  5:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-03-21 19:56 Need help mapping a C struct to Ada (null)
2001-03-21 21:25 ` tmoran
2001-03-22 20:53   ` tmoran
2001-03-21 22:21 ` Jeffrey Carter
2001-03-21 23:12   ` Florian Weimer
2001-03-30  5:59 ` David Thompson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox