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=3.8 required=5.0 tests=BAYES_00,INVALID_MSGID, RATWARE_MS_HASH,RATWARE_OUTLOOK_NONAME autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,ccc1fa4ead245afc X-Google-Attributes: gid103376,public From: "David C. Hoos, Sr." Subject: Re: Ada/C [GNAT]: Accessing C arrays from Ada Date: 1996/08/27 Message-ID: <01bb945c$8dc942e0$3b8371a5@dhoossr.iquest.com>#1/1 X-Deja-AN: 176842772 distribution: world references: <32225A96.4512F115@ix.netcom.com> content-type: text/plain; charset=ISO-8859-1 organization: DBH Enterprises, Inc. mime-version: 1.0 newsgroups: comp.lang.ada Date: 1996-08-27T00:00:00+00:00 List-Id: Hi Michael, Michael K Rohan wrote in article <32225A96.4512F115@ix.netcom.com>... > Hello, > > I'm trying to figure out the best way to use a C pointer as an array > from Ada. I have a C service function which returns the number of items > and a pointer to a vector of the items: > > Query(int *n, item** items); > > Interfacing from Ada is OK: I can get the number of items and the > pointer as an "access all Item", but how do I access the individual > items? > > Thank you, in advance, for any help/info, > Michael. > Assuming that the C function Query allocates memory for the items, you need to do something like the following: Here is a library-level Ada procedure which demonstrates what you want to do. It has been tested with gnat 3.05 on IRIX 5.3] VADS 623.53.3 on IRIX 5.3 and IRIX 6.2, and with gnat 3.04a on Win95. Note that there are many other ways this could have been done. For example, if we were not looking for Ada 83 compatibility, we could use the Interfaces.C.Pointers package from Ada 95's Annex B. This approach shows how to declare an array which takes on the attributes 'FIRST, 'LAST 'LENGTH, etc., corresponding to the number of elements returned by the C function. This allows passing the Ada array to another Ada subprogram, for example. with System; with Text_IO; procedure Do_Something is subtype ITEM_TYPE is INTEGER; -- Ada Equivalent of the C item type -- We use INTEGER here only for example. -- The type of an array of items type ITEM_ARRAY_TYPE is array (POSITIVE range <>) of ITEM_TYPE; -- The Ada specification of the C function procedure Query ( Number_Of_Items_Address : in System.ADDRESS; Item_Array_Address_Address : in System.ADDRESS ); -- The ada "implementation" of the C function is to interface to the C -- function's implementation. pragma INTERFACE (C, Query); The_Item_Array_Address : System.ADDRESS; -- This is where we will tell the Query function to put the address of the -- array of items it has allocated. The_Number_Of_Items : NATURAL; -- This is where we will tell the Query function to put the number of items -- in the array. begin -- Call the query function. Query ( Number_Of_Items_Address => The_Number_Of_Items'ADDRESS, Item_Array_Address_Address => The_Item_Array_Address'ADDRESS ); -- Now that we know how many items are in the array we can declare the array -- object. declare -- This is required for Ada 95. See further note below. The_Constant_Item_Array_Address : constant System.ADDRESS := The_Item_Array_Address; -- This is the array declaration. The_Item_Array : ITEM_ARRAY_TYPE (1 .. The_Number_Of_Items); -- This is the address clause which defines the location of the array of -- items. NOTE: In Ada95, Address clauses must have constant addresses, -- hence the need to declare the constant above. In Ada83 we could have -- just used the variable set by Query, directly. for The_Item_Array use at The_Constant_Item_Array_Address; begin -- Here we demonstrate that we have the correct data for i in The_Item_Array'RANGE loop Text_IO.Put_Line ( "Item (" & INTEGER'IMAGE (i) & " ) =>" & INTEGER'IMAGE (The_Item_Array (i)) ); end loop; end; end Do_Something; -- Example C source file for test -- #define length(a) (sizeof (a) / sizeof (* a)) -- static int data [] = {1,2,4,8,16,32,64,128}; -- /* NOTE: In a real implementation, the data is probably in dynamic memory, -- so, one would probably want an interface to "free", so that the memory -- could be deallocated from Ada code. */ -- void query (int * n, int ** items) -- { -- * n = length (data); -- * items = data; -- } -- David C. Hoos, Sr., http://www.dbhwww.com http://www.ada95.com