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=0.7 required=5.0 tests=BAYES_00,INVALID_MSGID, PDS_OTHER_BAD_TLD autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,a4c01e243163facf X-Google-Attributes: gid103376,public From: johndoe@world.std.com (j. doe) Subject: Re: C File Descriptors in Ada95 Date: 1996/07/22 Message-ID: #1/1 X-Deja-AN: 170102952 sender: johndoe@dsd.camb x-nntp-posting-host: dsd.camb.inmet.com references: <1996Jul19.225520.22396@nosc.mil> organization: myself? newsgroups: comp.lang.ada Date: 1996-07-22T00:00:00+00:00 List-Id: seibert@monkfish.nosc.mil (Jerome D. Seibert) writes: > > I have a need to make a call to a C function from an Ada-95 procedure, and > pass an open file descriptor to the C function. > > I have tried extending Ada.Text_IO and passing File.Stream to my C routine > and then dereferencing the pointer in the C code (this did not work). > I then tried performing an unchecked conversion from System.Address to > Integer'Access to convert File.Stream to an Integer access, dereference the > access pointer and passing this to my C routine as a file descriptor (int) > (this did not work either). > > Any info on how I might do this would be greatly appreciated. > the problem is that the component of the Text_IO type File_Type that you are attempting to make use of (File.Stream) is a pointer to a Stream, which is effectively meant to be a C FILEs , not a C FD. to get the FD out of the FILEs, you need to choose one of the following two solutions, depending on your desire for more portable code or not having to maintain an extra C function within your library. [1] create an analogous record to iob[] found in (which may differ from machine to machine) --ada.text_io.whatever_your_child_is_called --from /usr/include/stdio.h on a sparc 5 under SunOS 4.1.3 type iobuf is record Cnt : IC.int; Ptr : unsigned_char_ptr; Base : unsigned_char_ptr; Size : IC.int; Flag : IC.short; File : IC.unsigned_char; end record; for iobuf use record Cnt at 0 range 0 .. 31; Ptr at 4 range 0 .. 31; Base at 8 range 0 .. 31; Size at 12 range 0 .. 31; Flag at 16 range 0 .. 15; File at 18 range 0 .. 7; end record; type IOB_Ptr is access iobuf; function UC_To_IOB_Ptr is new Ada.Unchecked_Conversion (System.Address, IOB_Ptr); function C_Function_Using_FD (FD : in IC.int; Cmd : in IC.int; Size : in IC.long) return Integer; pragma Import (C, C_Function_Using_FD, "cFunctionUsingFD"); procedure Function_Using_File (F : File_Type ) is -- a private defined in Ada.Text_IO C_Stat : Integer; begin C_Stat := C_Function_Using_FD(Integer(UC_To_IOB_Ptr(F.Stream).File)); OR [2] you need to create another .c file/C function to extract the FD from the FILEs, and then pragma IMPORT that and use it (i.e. more portable from machine to machine, but also incorporates another C function) : #include int getFDfromFILEs(FILEs F) { return (int)(F->_file); } --in ada function Get_FD_From_Stream_Ptr( F : System.Address ) return Integer; pragma IMPORT( C, Get_Fd_From_Stream_Ptr, "getFDfromFILEs" ); --in ada.text_io.whatever_your_child_is_called function C_Function_Using_FD( FD : Integer ) return Integer; pragma IMPORT( C, C_Function_Using_FD, "cFunctionUsingFD" ); procedure Function_Using_File( F : File_Type ); Status : Integer; begin Status := C_Function_Using_FD( FD => Get_FD_From_Stream_Ptr( F.Stream ) );