Interfacing with C: access/out parameters

From: Jano (notelacreas_at_porfavor.no)
Date: 08/30/04


Date: Mon, 30 Aug 2004 19:30:37 +0200

Hi,

I'm doing some C interfacing and I have a doubt about what's the proper
way to do something "the Ada Way(tm)".

If I'm not mistaken, reading the relevant ARM section I see that C
pointer parameters can be mapped either with access and out parameters.

I'm interfacing to some C functions which fill a data structure passed
via pointer, and which return an error code I don't want to discard. So
Firstly, I define a function like:

function Blah (Datum : access Data) return C.Int;
pragma Import (C, Blah);

since I can't use out mode in functions. Data is a record defined
elsewhere with C convention.

Now, I would want to have a wrapper procedure more Ada-fied like:

Procedure Ada_Blah (Datum : out Data);
-- May raise some exception

And my doubt, finally, is: can I ensure somehow that Datum is passed by
reference?, so I can do inside Ada_Blah [1]:

Helper : aliased Datum;
For Helper'Address use Datum'Address;
if Thin_Package.Blah (Helper'Access) = Error_Value then
    raise My_Error;
end if;

I know that tagged types are always passed by reference, but I fear that
the tag will ruin the record structure. (My tests show indeed this is
happening). It seems my only solution is to use a limited modifier. Am I
right in that this would work properly in any compliant compiler? I'm
ready to lose the copy operation.

I'd want to not use a wrapper type for the types implicated in this kind
of functions... nor explicitely do a local copy, because the function
may appear in code called at high frequency rates. Is this possible?

Thanks in advance,

A. Mosteo.

[1] This works with Gnat, but is it portable by some reason I ignore, or
simply because Gnat uses reference passing for out record parameters?

P.s: A quite old thread here says:

"Simon says

   Yes, I quite understand that; the problem is that the C subprogram is
   a function and therefore can't be declared with an out parameter. I
   guess I could use the DEC pragma (valued_subprogram??), but that would
   be a tad implementation-dependent!

Deward says

Sure, it would be a bit implementation dependent. At the moment it would
only work on GNAT and DEC, though I would like to see this particular
pragma (Import_Valued_Procedure) implemented more widely, since it is
very useful in interfacing.

It is indeed the sad consequence of the rule forbidding out parameters
in functions that the horrible copy in your suggested solution is the
only truly portable way of doing things."

The last paragraph is discouraging. n
:(



Relevant Pages

  • Interfaces and C++ references (off-topic)
    ... When in the "client code", that is, when not interfacing with COM calls, ... what do you think about passing COM interfaces by reference (as done in ... I prefer it to pointers for the usual reasons we prefer ...
    (microsoft.public.vc.atl)
  • Re: Improving Adas image - Was: 7E7 Flight Controls Electronics
    ... but interfacing with C libraries is probably universal ... for real-life Ada programs, ... people who changed the underlying gcc could go through the GNAT ...
    (comp.lang.ada)
  • Re: Interfacing Ada with Ada
    ... I imagined once something like interfacing old code with C and then ... But linking may be hard, ... You need to link the GNAT ...
    (comp.lang.ada)
  • Question about Star Office API
    ... The code below is Star Basic, but it is interfacing to a Java ... document format or suffix then returns a reference to the the ... sort of a document service such ...
    (comp.lang.java.help)
  • [gnat] Where did pragma CPP_Destructor go?
    ... I asked this on gcc-help but it doesn't look as though Ada people ... The section on C++ interfacing in the GNAT User's Guide for GCC 4.3.0 ...
    (comp.lang.ada)