comp.lang.ada
 help / color / mirror / Atom feed
From: Bob Wells #402 <wel@EUROCONTROL.DE>
Subject: Re: C-Ada Import of struct's -- Help
Date: Tue, 18 Oct 1994 11:20:30 +0100
Date: 1994-10-18T11:20:30+01:00	[thread overview]
Message-ID: <9410181020.AA08716@eurocontrol.de> (raw)

mmcnett@SPARC53.CS.UIUC.EDU writes .....

> I am having a problem on how to implement the following C structure in
> Ada.  The problem is I need to interface into a C procedure by passing
> it this structure so that it may update the information contained within
> it.  It will then return any changes made to the structure.  Much of
> the code in the C routine depends on this structure and I don't want to
> make changes to the procedure since many other routines also depend on
> the struct.
>
>
> C-structure:
>
> struct queue_noncyc_s {
>     char *debugname;          /* name for debugging purposes */
>     int length;               /* length (max items+1) of queue */
>     int first, last;          /* begin and end of queue */
>     Qitem *entries;           /* array[length] of entries */
> };
>
>
> Ada Code:
> procedure DDInitDisk (????????????); -- want to pass in the queue struct
> pragma IMPORT (C, DDInitDisk, "DDInitDisk");
>
> Thanks in advance,
>

G'day Michael,

After having interfaced many large C structures to Ada myself I
would suggest the following.

First define a trivial C function that will have as a parameter
a pointer to the desired structure.

#include queue_noncyc_s_defs.h

int DDInitDisk (queue_noncyc_s *queue)

{

      /* Code that does the updating of the queue structure */
      /* by calling the C function.                         */

      /* I've got it returning a status value so that you   */
      /* may return the status via the Ada I/O.             */

      /* By using a simple interface you can also verify    */
      /* what happens by using printf's to isolate the      */
      /* structure on the Ada side or the C side. Also both */
      /* before and after the call to the actual C updating */
      /* function which helps to isolate any errors.        */

      /* By using a pointer as the method of interface you  */
      /* are also making the interface much more portable.  */

}

Then "attack" the Ada types.

Look in the documentation for your compiler. Sometimes there is
defined, like for Verdix, a mapping of the Ada types to the C types.

package Queue_Interface is

  type Debug_Name_String is access String;

  -- As you haven't said what entries are, I'll assume something trivial
  -- like an array of integers,

  type Q_Item is array ( Natural range <> ) of Integer;
  type Q_Item_Ptr is access Q_Item;

  type Queue_Noncyc_S is
    record
      Debug_Name : Debug_Name_String;
      Length     : Integer;
      First      : Integer;
      Last       : Integer;
      Entries    : Q_Item_Ptr;
    end record;

  type Queue_Noncyc_S_Ptr is access Queue_Noncyc_S;

  -- Define an aggregate so that you can initialize the structure (so you
  -- won't get Constraint_Errors (via Access_Check) when you try to look
  -- at an unallocated variable.

  Init_Queue_Noncyc_S : Queue_Noncyc_S := ( Debug_Name => new String (1 .. 1),
                                            Length     => 0,
                                            First      => 0,
                                            Last       => 0,
                                            Entries    => new Q_Item (1 .. 1));

  -- Define your interfacing Ada function and the interfacing pragma.

  function DDInitDisk ( Queue : in Queue_Noncyc_S_Ptr )
    return Integer;

  pragma Interface ( C, DDInitDisk, "DDInit_Disk" );

  -- Declare your queue and initialize it.

  My_Queue : Queue_Noncyc_S_Ptr :=
    new Queue_Noncyc_S'(Init_Queue_Noncyc_S);

  -- You will have to define a function to search for the length of the
  -- debug string if you want to read it, so that you can declare a
  -- matching Ada debug string. (You would ordinarily have to define the
  -- same for the length of the entries array but as it's provided as a
  -- part of the structure then you don't need to). Or you could define a
  -- general C string to Ada string (and vice versa) function.

  function Debug_string_Length ( Str : Debug_Name_String ) return Integer;

end Queue_Interface;

  -----------------------

Then your calls to update the queue will be of the form

  Results := Queue_Interface.DDInitDisk ( Queue => My_Queue );

It is my experience that getting involved with discriminants gives
little benefits in interfacing. Keeping the interfacing object as
simple as possible makes the interface more robust and much more
easy to debug.

I hope this helps.

BTW The largest structures I have had to interface were complete X.400
headers with STAMINA (P77/P78) extensions and also containing ASN.1
representation structures.

@                   --------
@          ////  - ( G'day! )
@         (o o)     --------
@ ----oOO--(_)--OOo--------------------------------------------------------
  Bob Wells                             "For every action there is an equal
                                         and opposite government program."
@ INTERNET: wel@eurocontrol.de                 CompuServe:      100272,3004
@ The Ada WWW Server is http://lglwww.epfl.ch/Ada/                 Team Ada
@ For exciting Ada info enter 'finger wel@s4ecawel.eurocontrol.de'



             reply	other threads:[~1994-10-18 10:20 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1994-10-18 10:20 Bob Wells #402 [this message]
1994-10-18  9:58 ` C-Ada Import of struct's -- Help David Emery
1994-10-18 19:11   ` Robert Dewar
1994-10-19 10:02     ` David Emery
1994-10-20  0:36     ` Keith Thompson @pulsar
  -- strict thread matches above, loose matches on Subject: below --
1994-10-19 13:57 Bob Wells #402
1994-10-18  3:34 mcnett michael david
1994-10-18  9:48 ` David Emery
replies disabled

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