comp.lang.ada
 help / color / mirror / Atom feed
From: Jeffrey Carter <spam@spam.com>
Subject: Re: Interfacing with C: access/out parameters
Date: Tue, 31 Aug 2004 18:26:33 GMT
Date: 2004-08-31T18:26:33+00:00	[thread overview]
Message-ID: <tp3Zc.3869$8d1.573@newsread2.news.pas.earthlink.net> (raw)
In-Reply-To: <2pivcgFl9kl2U1@uni-berlin.de>

Alex R. Mosteo wrote:

> It's for these reasons that I would want to have the optimal high level 
> solution, and eliminating the copy of the returned data seems a sensible 
>  desire. There is that mentioned Import_Valued_Procedure in Gnat which 
> addresses this Ada shortcoming, but talking about a binding, I want it 
> to be totally portable if possible.
> 
> As per the C convention types all around the place, my intention is to 
> build (if time permits) a thick binding over this thin binding, so that 
> can be isolated later.

Conversion to native Ada types will probably add assignment anyway.

> Further ideas? Is there anything definitely unadvisable in my original 
> solution? (The one using limited/tagged types and 'Address).

I would not advise using an overlay if you want to insure portability. 
For a convention C function, Ada automatically converts parameters of 
composite types to pointers (see Annex B), so you can "cheat" and use 
this fact to pass a pointer to your record. I've done a similar thing in 
a binding to fgets:

procedure Get (Item :    out String;
                Last :    out Natural;
                File : in     File_Handle := Standard_Input)
is
    Buffer : Char_Array (1 .. Item'Length + 1);
    -- May get a warning about Buffer never assigned a value
    Result : File_Handle; -- Dummy pointer

    function C_Get (Item : Char_Array; Length : Int; File : File_Handle)
    return File_Handle;
    pragma Import (C, C_Get, "fgets");
    -- Item should be "out", but since Import (C) will pass a pointer,
    -- this works.
begin -- Get
    Result := C_Get (Buffer, Buffer'Length, File);
    -- This fills Buffer, but Ada doesn't know that.

    if Result = null then
       raise EOF_Breached;
    end if;

    Extract : declare
       Value : constant String := To_Ada (Buffer);
    begin -- Extract
       if Value (Value'Last) = LF then -- Remove line terminator
          Last := Item'First + Value'Length - 2;
          Item (Item'First .. Last) :=
             Value (Value'First .. Value'Last - 1);
       else
          Last := Item'First + Value'Length - 1;
          Item (Item'First .. Last) := Value;
       end if;
    end Extract;
end Get;

-- 
Jeff Carter
"I'm particularly glad that these lovely children were
here today to hear that speech. Not only was it authentic
frontier gibberish, it expressed a courage little seen
in this day and age."
Blazing Saddles
88




  parent reply	other threads:[~2004-08-31 18:26 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-08-30 17:30 Interfacing with C: access/out parameters Jano
2004-08-30 19:06 ` Jeffrey Carter
2004-08-31  9:41   ` Alex R. Mosteo
2004-08-31  9:48     ` Alex R. Mosteo
2004-08-31 18:26     ` Jeffrey Carter [this message]
2004-09-01  9:46       ` Alex R. Mosteo
2004-08-31  7:54 ` Egil H. H�vik
2004-08-31  9:11   ` Egil H. H�vik
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox