* Ada address of operator? @ 1999-02-09 0:00 Danny 1999-02-09 0:00 ` Niklas Holsti ` (2 more replies) 0 siblings, 3 replies; 5+ messages in thread From: Danny @ 1999-02-09 0:00 UTC (permalink / raw) Hi, I'm trying to use a C library in an Ada function and a typical prototype from this library would be struct AType; struct AnotherType; int getObject( AType *pType, AnotherType **ppAnotherType ); I've imported the function okay and it is being called. The purpose of the function is to use AType as an IN parameter and return a pointer to AnotherType, which will be pointed to by ppAnotherType if you get what I mean. In Ada I have corresponding records for AType & AnotherType and have declared AnotherTypePtr and AnotherTypePtrPtr. What I think I need to do is pAnotherType : AntherTypePtr; ppAnotherType : AnotherTypePtrPtr; but I need to assign ppAnotherType the address of pAnotherType, the equivalent C code would be AnotherType *pAnotherType; AnotherType **ppAnotherType = &pAnotherType; any suggestions? -Danny ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Ada address of operator? 1999-02-09 0:00 Ada address of operator? Danny @ 1999-02-09 0:00 ` Niklas Holsti 1999-02-10 0:00 ` Nick Roberts 1999-02-11 0:00 ` Matthew Heaney 2 siblings, 0 replies; 5+ messages in thread From: Niklas Holsti @ 1999-02-09 0:00 UTC (permalink / raw) Danny wrote: (snipped; question on C operator "&" = "address of" in Ada) Use the 'Access attribute. Note the use of "all" in the declaration of the access types, and "aliased" in the declaration of the variable you are accessing. Example: package Ptrs is type AType is record X : integer; end record; type AnotherType is record Y : integer; end record; type ATypePtr is access all AType; type AnotherTypePtr is access all AnotherType; type AnotherTypePtrPtr is access all AnotherTypePtr; -- pAnotherType : aliased AnotherTypePtr; ppAnotherType : AnotherTypePtrPtr := pAnotherType'access; end Ptrs; But are you sure you need all those "Ptr"s? The standard Ada/C binding from pragma Import (C...) supplies some *'s automatically; see LRM B.3(63-84). - Niklas Working at but not speaking for Space Systems Finland Ltd ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Ada address of operator? 1999-02-09 0:00 Ada address of operator? Danny 1999-02-09 0:00 ` Niklas Holsti @ 1999-02-10 0:00 ` Nick Roberts 1999-02-12 0:00 ` Nick Roberts 1999-02-11 0:00 ` Matthew Heaney 2 siblings, 1 reply; 5+ messages in thread From: Nick Roberts @ 1999-02-10 0:00 UTC (permalink / raw) Danny, In this instance, you do not need to declare a pointer-to-a-pointer type in Ada. Instead, use the fact that Ada interprets 'out' parameters as pointers when interfacing to C to provide the second level of indirection (see RM95 B.1, B.2, and B.3, especially B.3(68)). For example (completely contrived): type File_Handle is Interfaces.C.int; type File_Descriptor_Block is record Name_1, Name_2: Interfaces.C.char_array(1..11); ... end record; pragma Convention(C,File_Descriptor_Block); type File_Handle_Access is access all File_Handle; type File_Descriptor_Block_Access is access all File_Descriptor_Block; pragma Convention(C,File_Handle_Access); pragma Convention(C,File_Descriptor_Block_Access); function Get_FDB (Handle: in File_Handle_Access; FDBA: out File_Descriptor_Block_Access) return File_Handle; pragma Import(C,Get_FDB,"GetFDB"); [Apologies for the horrible formatting btw.] Note the assiduous use of pragma Convention, to (help to) ensure that Ada entities are implemented in a way compatible with their C equivalents. If you are lucky, the Ada compiler will not rearrange the components of a record type which has the C convention applied to it (otherwise, you will have to use a record representation clause - see RM95 13.5.1). The parameter 'FDBA' is an 'out' parameter of an access type, so it will correspond to a C 'pointer-to-a-pointer'. The corresponding C function prototype could be: int GetFDB(int *phand, FDB **ppfdb); I am assuming the parameter semantics of this function to be that the file handle pointed to by 'phand' is passed into the function, and a pointer to the file's FDB is passed out (into 'ppfdb'). (And the handle (or -1 for an error) is returned by the function, as a convenience). Back in Ada, the access value put into the parameter 'FDBA' can be assigned to other objects of the same type without any further ado; record components will be dereferenced automatically, otherwise the '.all' qualifier must be added to cause dereferencing. For example (again totally contrived): declare FDBA: File_Descriptor_Block_Access; Vital_FDBA: File_Descriptor_Block_Access := null; -- to emphasise initialisation Vital_FDB: File_Descriptor_Block; begin ... for i in Active_File_Index loop if Get_FDB(Active_File(i),FDBA) >= 0 then if ... then Vital_FDBA := FDBA; end if; end if; end loop; if Vital_FDBA /= null then -- at this point Vital_FDBA accesses one of the FDBs returned by Get_FDB if Interfaces.C.To_Ada(Vital_FDBA.Name_1) /= "XYZDATA DAT" then Vital_FDB := Vital_FDBA.all; -- copies the FDB data itself ... end if; else ... end if; end; Note, also, the style of Ada identifiers I use, which are typical for Ada programming (although tastes vary, of course). I think I speak for pretty well all Ada programmers in saying that the '.all' is one of the least liked aspects of Ada syntax (but not the automatic dereferencing, which only a few dislike). One final point. It is often vitally important to check the validity of parameters you pass into an external routine before making the call, and the validity and status of output parameters afterwards. The reason why is that these routines do not have recourse to the Ada exception mechanism to report errors. For example, the above code does not check 'Active_File(i)' for being null. It should. ------------------------------------------- Nick Roberts "The Prophylactic Didactic" ------------------------------------------- ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Ada address of operator? 1999-02-10 0:00 ` Nick Roberts @ 1999-02-12 0:00 ` Nick Roberts 0 siblings, 0 replies; 5+ messages in thread From: Nick Roberts @ 1999-02-12 0:00 UTC (permalink / raw) Spotted two errors in my own code instantly! Boo hoo :-( type File_Handle is Interfaces.C.int; should be type File_Handle is new Interfaces.C.int; and I intended for i in Active_File_Index loop to be for i in Active_File_Index'Range loop ------------------------------------------- Nick Roberts "The Prophylactic Didactic" ------------------------------------------- ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Ada address of operator? 1999-02-09 0:00 Ada address of operator? Danny 1999-02-09 0:00 ` Niklas Holsti 1999-02-10 0:00 ` Nick Roberts @ 1999-02-11 0:00 ` Matthew Heaney 2 siblings, 0 replies; 5+ messages in thread From: Matthew Heaney @ 1999-02-11 0:00 UTC (permalink / raw) Danny <clarked@aston.ac.uk> writes: > I'm trying to use a C library in an Ada function and a typical prototype > from this library would be > > struct AType; > struct AnotherType; > > int getObject( AType *pType, AnotherType **ppAnotherType ); If you use Import_Valued_Procedure (in GNAT), then you may not need to use pointers at all: procedure Get_Object (Return_Value : out Int; In_Param : in A_Type; Out_Param : out Another_Type); pragma Import_Valued_Procedure (Get_Object, "getObject"); --or something like that ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~1999-02-12 0:00 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1999-02-09 0:00 Ada address of operator? Danny 1999-02-09 0:00 ` Niklas Holsti 1999-02-10 0:00 ` Nick Roberts 1999-02-12 0:00 ` Nick Roberts 1999-02-11 0:00 ` Matthew Heaney
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox