* how to read C extern variables from Ada?
1999-02-28 0:00 nabbasi@pacbell.net how to read C extern variables from Ada?
1999-02-28 0:00 ` nabbasi@pacbell.net Matthew Heaney
@ 1999-02-28 0:00 ` David C. Hoos, Sr.
1999-03-02 0:00 ` nabbasi@pacbell.net Stephen Leake
2 siblings, 0 replies; 4+ messages in thread
From: David C. Hoos, Sr. @ 1999-02-28 0:00 UTC (permalink / raw)
how to read C extern variables from Ada? wrote in message
<7bbd3c$gf7@drn.newsguy.com>...
>Hello,
>
>It is easy to interface to C from Ada. But one problem that I could not
>see mentioned in annex B, is how to get access to 'extern' variables.
>
>For example, I can call getopt() from Ada. But the problem is that getopt()
>sets values into an extern variables that are defined is C header files,
>and so can be read from C client programs after the call to getopt()
>returns.
>
>--------------------
>SYNOPSIS
> #include <unistd.h>
>
> int getopt(int argc, char * const argv[], const char *optstring);
> extern char *optarg;
> extern int optind, opterr, optopt;
>-----------------------
>
>So, in the above, after I call getopt(), I need a way to 'read' optarg.
There
>is no C API to read optarg. So, How to do this in Ada??
>
The simple answer is that one uses pragma import, e.g.:
Option_Argument : Interfaces.C.Char_Array;
pragma Import (C. Option_Argument, "optarg");
But, the details get a little messy. Here's a possible implementation:
--- begin source code ---
with Ada.Command_Line;
with Ada.Text_Io;
with Interfaces.C.Pointers;
with System;
procedure Command_Line_Options is
package C_String_Pointers is new Interfaces.C.Pointers
(Index => Interfaces.C.Size_T,
Element => Interfaces.C.Char,
Element_Array => Interfaces.C.Char_Array,
Default_Terminator => Interfaces.C.Nul);
type C_String_Vector is array (Interfaces.C.Size_T range <>) of
aliased C_String_Pointers.Pointer;
package C_String_Vector_Pointers is new Interfaces.C.Pointers
(Index => Interfaces.C.Size_T,
Element => C_String_Pointers.Pointer,
Element_Array => C_String_Vector,
Default_Terminator => Null);
subtype String_Pointer is C_String_Pointers.Pointer;
subtype C_String_Vector_Pointer is C_String_Vector_Pointers.Pointer;
use type Interfaces.C.Char_Array;
use type Interfaces.C.Int;
use type C_String_Pointers.Pointer;
function Next_Option_Character_Pos
(Argument_Count : in Interfaces.C.Int;
Argument_Vector_Pointer : in C_String_Vector_Pointer;
Option_String : in Interfaces.C.Char_Array)
return Interfaces.C.Int;
pragma Import (C, Next_Option_Character_Pos, "getopt");
Argument_Vector_Pointer : C_String_Vector_Pointer;
pragma Import (C, Argument_Vector_Pointer, "gnat_argv");
Argument_Vector : constant C_String_Vector :=
C_String_Vector_Pointers.Value (Ref => Argument_Vector_Pointer);
Argument_Count : constant Interfaces.C.Int := Argument_Vector'Length - 1;
Option_Argument_Pointer : C_String_Pointers.Pointer;
pragma Import (C, Option_Argument_Pointer, "optarg");
Option_Character_Pos : Interfaces.C.Int := 0;
Option_Character : Character;
Option_Index : Interfaces.C.Int;
pragma Import (C, Option_Index, "optind");
Option_Error : Interfaces.C.Int;
pragma Import (C, Option_Error, "opterr");
Option_Option : Interfaces.C.Int;
pragma Import (C, Option_Option, "optopt");
begin
Ada.Text_Io.Put_Line
("Argument count =>" & Interfaces.C.Int'Image (Argument_Count));
for A in Argument_Vector'First ..
Interfaces.C.Size_T'Pred (Argument_Vector'Last) loop
Ada.Text_Io.Put_Line
("Argument (" & Interfaces.C.Size_T'Image (A) & ") is """ &
Interfaces.C.To_Ada
(C_String_Pointers.Value (Argument_Vector (A))) &
"""");
end loop;
Option_Error := 1;
loop
Option_Character_Pos := Next_Option_Character_Pos
(Argument_Count => Argument_Count,
Argument_Vector_Pointer => Argument_Vector_Pointer,
Option_String => "a:bc" & Interfaces.C.nul);
exit when Option_Character_Pos < 0 or else Option_Character_Pos >
255;
Option_Character := Character'Val (Option_Character_Pos);
Ada.Text_Io.Put_Line
("Option_Index =" &
Interfaces.C.Int'Image (Option_Index));
Ada.Text_Io.Put_Line
("Option_Option =" &
Interfaces.C.Int'Image (Option_Option));
Ada.Text_Io.Put_Line
("Option_Character =" & Option_Character);
for A in Argument_Vector'First ..
Interfaces.C.Size_T'Pred (Argument_Vector'Last) loop
Ada.Text_Io.Put_Line
("Argument (" & Interfaces.C.Size_T'Image (A) & ") is """ &
Interfaces.C.To_Ada
(C_String_Pointers.Value (Argument_Vector (A))) &
"""");
end loop;
if Option_Argument_Pointer /= null then
Ada.Text_Io.Put_Line
("Option argument = """ &
Interfaces.C.To_Ada
(C_String_Pointers.Value (Option_Argument_Pointer)));
end if;
end loop;
end Command_Line_Options;
--- end source code ---
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: nabbasi@pacbell.net
1999-02-28 0:00 nabbasi@pacbell.net how to read C extern variables from Ada?
1999-02-28 0:00 ` nabbasi@pacbell.net Matthew Heaney
1999-02-28 0:00 ` how to read C extern variables from Ada? David C. Hoos, Sr.
@ 1999-03-02 0:00 ` Stephen Leake
2 siblings, 0 replies; 4+ messages in thread
From: Stephen Leake @ 1999-03-02 0:00 UTC (permalink / raw)
how to read C extern variables from Ada? <how@newsguy.com> writes:
> Hello,
>
> It is easy to interface to C from Ada. But one problem that I could not
> see mentioned in annex B, is how to get access to 'extern' variables.
>
> For example, I can call getopt() from Ada. But the problem is that getopt()
> sets values into an extern variables that are defined is C header files,
> and so can be read from C client programs after the call to getopt()
> returns.
>
> --------------------
> SYNOPSIS
> #include <unistd.h>
>
> int getopt(int argc, char * const argv[], const char *optstring);
> extern char *optarg;
> extern int optind, opterr, optopt;
> -----------------------
>
> So, in the above, after I call getopt(), I need a way to 'read' optarg. There
> is no C API to read optarg. So, How to do this in Ada??
Ada code to import 'optarg':
optarg : Interfaces.C.strings.Chars_Ptr;
pragma Import (C, optarg, "optarg");
I haven't compiled this, but it should work with GNAT.
> ps. offcourse I could write a small C stub that the Ada program calls, and
> then it calls getopt(), and this C stub could read the extern
> variables. and I define an API to this C stub function to return these
> variables via function call. But I wanted to see if I can do the whole thing
> in 100% pure Ada :), it also makes the Makefile simpler. This is GNAT 3.11p.
I have tried to import an object exported by a DLL, using ObjectAda on
Windows NT, and that doesn't work. So I had to add an access function
to the DLL. But in the above, getopt() is probably not in a DLL, but
just a normal library, so you should be ok.
-- Stephe
^ permalink raw reply [flat|nested] 4+ messages in thread