From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6ec0e822a8924768,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-10-18 05:16:40 PST Path: bga.com!news.sprintlink.net!howland.reston.ans.net!europa.eng.gtefsd.com!paladin.american.edu!auvm!EUROCONTROL.DE!wel Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU Newsgroups: comp.lang.ada Message-ID: <9410181020.AA08716@eurocontrol.de> Date: Tue, 18 Oct 1994 11:20:30 +0100 Sender: Ada programming language From: Bob Wells #402 Subject: Re: C-Ada Import of struct's -- Help Date: 1994-10-18T11:20:30+01:00 List-Id: 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'