From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID, WEIRD_QUOTING autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,c6e88c9c6862d6b4 X-Google-Attributes: gid103376,public From: "David C. Hoos, Sr." Subject: how to read C extern variables from Ada? Date: 1999/02/28 Message-ID: <5lkp7H5Y#GA.155@pet.hiwaay.net>#1/1 X-Deja-AN: 449734509 References: <7bbd3c$gf7@drn.newsguy.com> Newsgroups: comp.lang.ada X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Date: 1999-02-28T00:00:00+00:00 List-Id: 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 > > 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 ---