comp.lang.ada
 help / color / mirror / Atom feed
* 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-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

* 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

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