From: qunying on
Hi,

I am learning Ada and try to test the interface with C.

for this function, what is the best way to define the function in Ada?

int xcb_parse_display(const char *name, char **host, int *display, int
*screen);

function parse_display (Name : String; Host: ??; Display :
Integer_Ptr; Screen : Integer_Ptr) return Integer;
pragma Import (C, parse_display, "xcb_parse_display");

Where Integer_Ptr is access Integer;
How to define the type for char **? Sould I use "type char_ptr_ptr is
access char_ptr;" where char_ptr is defined in Interfaces.C; or there
is a better way to do it?

Thanks


From: Dmitry A. Kazakov on
On Fri, 25 Jan 2008 21:05:02 -0800 (PST), qunying wrote:

> I am learning Ada and try to test the interface with C.
>
> for this function, what is the best way to define the function in Ada?
>
> int xcb_parse_display(const char *name, char **host, int *display, int
> *screen);
>
> function parse_display (Name : String; Host: ??; Display :
> Integer_Ptr; Screen : Integer_Ptr) return Integer;
> pragma Import (C, parse_display, "xcb_parse_display");
>
> Where Integer_Ptr is access Integer;

Name : Interfaces.C.char_array

and use To_C in order to pass a String there. Ada's String is not C's
char[]

Display : access Interfaces.C.int

Firstly Integer is not necessarily int, the built-in package Interfaces.C
provides integer types compatible with C. Secondly in out mode will do the
trick where int * is used as an in-out parameter rather than a pointer to
an array. Unfortunately you have a function, so in out is illegal.
Therefore access Interfaces.C.int instead.

> How to define the type for char **? Sould I use "type char_ptr_ptr is
> access char_ptr;" where char_ptr is defined in Interfaces.C; or there
> is a better way to do it?

Like with int *, that depends on the semantics. If the idea is to return a
pointer to a string then just tell so:

Host : access Interfaces.C.Strings.chars_ptr
Screen : access Interfaces.C.int

Surely, you would like to make a wrapper around the mess to make it more
Ada-friendly:

type Display_ID is private; -- An opaque handle to
type Screen_ID is private;
-- This either does the job or raises an exception
procedure Parse_Display
( Name : String;
Host : out Unbounded_String;
Display : out Display_ID;
Screen : out Screen_ID
);
....
private
type Display_ID is new Interfaces.C.int;
type Screen_ID is new Interfaces.C.int;

....
procedure Parse_Display
( Name : String;
Host : out Unbounded_String;
Display : out Display_ID;
Screen : out Screen_ID
) is
function Internal
( Name : Interfaces.C.char_array;
Host : access Interfaces.C.Strings.chars_ptr;
Display : access Display_ID;
Screen : access Screen_ID
) return Interfaces.C.int;
pragma Import (C, Internal, "xcb_parse_display");

Display_Value : aliased Display_ID;
Screen_Value : aliased Screen_ID;
Host_Value : aliased Interfaces.C.Strings.chars_ptr;
Result : Interfaces.C.int :=
Internal
( Name => To_C (Name),
Host => Host_Value'Access,
Display => Display_Value'Access,
Screen => Screen_Value'Access
);
begin
if Result = 0 then
Host := To_Unbounded_String (To_Ada (Host_Value));
Display := Display_Value;
Screen := Screen_Value;
else
raise <Something Appropriate>;
end if;
end Parse_Display;

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Martin Krischik on
qunying wrote:

> Hi,
>
> I am learning Ada and try to test the interface with C.
>
> for this function, what is the best way to define the function in Ada?
>
> int xcb_parse_display(const char *name, char **host, int *display, int
> *screen);

function parse_display (
Name : in Interfaces.C.Strings.char_array_access;
Host : access Interfaces.C.Strings.char_array_access;
Display : access Interfaces.C.int;
Screen : access Interfaces.C.int)
return Interfaces.C.int;

See:

http://www.adaic.com/standards/05rm/html/RM-B-3.html

Martin

--
mailto://krischik(a)users.sourceforge.net
Ada programming at: http://ada.krischik.com
From: Stefan Lucks on
On Sat, 26 Jan 2008, Dmitry A. Kazakov wrote:

> Surely, you would like to make a wrapper around the mess to make it more
> Ada-friendly:

Such a wrapper looks like a typical "please inline me" function:

> type Display_ID is private; -- An opaque handle to
> type Screen_ID is private;
> -- This either does the job or raises an exception
> procedure Parse_Display ( [...] );
pragma inline (Parse_Display); -- *** this seems to make sense ***

> private
> ...
> procedure Parse_Display ( [...] ) is
> function Internal ( [...] ) return Interfaces.C.int;
> pragma Import (C, Internal, "xcb_parse_display");
[...]
> Result : Interfaces.C.int := Internal ( [...] );
> begin
> if Result = 0 then
[...]
> else
> raise [...];
> end if;
> end Parse_Display;


--
Stefan Lucks (moved to Bauhaus-University Weimar, Germany)
<Stefan.Lucks at medien.uni-weimar.de>
------ I love the taste of Cryptanalysis in the morning! ------


From: qunying on
Thank you for all the help! You guys are awesome. As my learning, I
try to produced a Ada binding to the XCB library. Seems there is
still quite some road for me to go.