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
next prev 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