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.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC,WEIRD_QUOTING autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,381c317569686183,start X-Google-Attributes: gid103376,public From: Brett Kettering Subject: char **'s coming into Ada Date: 1997/03/14 Message-ID: <332995FC.8B0@llnl.gov> X-Deja-AN: 225667351 Organization: LLNL Reply-To: brettk@llnl.gov Newsgroups: comp.lang.ada Date: 1997-03-14T00:00:00+00:00 List-Id: This is a multi-part message in MIME format. --------------61C26E7619C5 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit I have been doing a lot of work interfacing some C code to an Ada routine. I have a short version of an interesting problem. I am using GNAT V3.07 and gcc's C compiler on Solaris 2.5. In a C function I allocate memory and assign some strings to an argv (char **) and pass that char ** and an argc (integer) to an Ada procedure. The Ada procedure receives the char ** into an Interfaces.C.Strings.chars_ptr_array and the argc into an Interfaces.C.size_t. It comes in just fine, but when you start looking at the attributes of the array (chars_ptr_array) you see that: 'first = 0 'last = -1 'length = 0 as if it were a null, or empty, array. If you try to loop over 'range or 'first .. 'last you'll get a core dump. If you loop over 'first .. 'first+argc-1 it works just fine. My questions: 1) Am I doing something wrong here that I can't get the attributes of the array? 2) If not, is there a way to get Ada to recognize it? Run the program and you'll find it interesting to see that even when it core dumps it still iterates over the array (just runs off the end), even though 'last is supposedly -1 and if you loop from 0 .. -1 you shouldn't ever execute a statement of the loop. -- ------------------------------------------------------------------------------ Brett M. Kettering LLNL - P.O. Box 808 L-493 Livermore, CA. 94550 E-mail : brettk@llnl.gov Voice : (510) 423-3467 FAX : (510) 422-1930 ------------------------------------------------------------------------------ --------------61C26E7619C5 Content-Type: text/plain; charset=us-ascii; name="c_malloc_fun.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="c_malloc_fun.c" #include #include #include #include "c_malloc_fun.h" /* typedef void Note_Argv( char *argv[], int argc ); */ /*---------------------------------------------------------------------------*\ * * This function allocates memory to argv and puts some strings in it. * It calls Note_The_Argv to hand you the argv and argc that are allocated. * \*---------------------------------------------------------------------------*/ extern void Hand_You_Argv( Note_Argv *Note_The_Argv ) { char **argv; int i; argv = ( char ** ) malloc ( 6 * sizeof( char * )); argv[0] = ( char * ) malloc( strlen( "Fun Hand Argument 1" ) + 1 ); argv[1] = ( char * ) malloc( strlen( "Fun Hand Argument 2" ) + 1 ); argv[2] = ( char * ) malloc( strlen( "Fun Hand Argument 3" ) + 1 ); argv[3] = ( char * ) malloc( strlen( "Fun Hand Argument 4" ) + 1 ); argv[4] = ( char * ) malloc( strlen( "Fun Hand Argument 5" ) + 1 ); argv[5] = ( char * ) malloc( strlen( "Fun Hand Argument 6" ) + 1 ); strcpy( argv[0], "Fun Hand Argument 1" ); strcpy( argv[1], "Fun Hand Argument 2" ); strcpy( argv[2], "Fun Hand Argument 3" ); strcpy( argv[3], "Fun Hand Argument 4" ); strcpy( argv[4], "Fun Hand Argument 5" ); strcpy( argv[5], "Fun Hand Argument 6" ); Note_The_Argv( argv, 6 ); for ( i = 0; i < 6; i++ ) { free(( char * ) argv[i] ); } free(( char ** ) argv ); } /*---------------------------------------------------------------------------*\ * * This function takes in an argv and an argc and prints the contents * to standard output. * \*---------------------------------------------------------------------------*/ extern void Print_Argv( char *argv[], int argc ) { int i; printf( "\n\nPrinting contents of Argv from \"C\" ...\n" ); printf( "--------------------------------------\n" ); for ( i = 0; i < argc; i++ ) { printf( "Argv[%d]: \"%s\"\n", i, argv[i] ); } printf( "--------------------------------------\n" ); } --------------61C26E7619C5 Content-Type: text/plain; charset=us-ascii; name="c_malloc_fun.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="c_malloc_fun.h" #ifndef __C_MALLOC_FUN_H #define __C_MALLOC_FUN_H typedef void Note_Argv( char *argv[], int argc ); /*---------------------------------------------------------------------------*\ * * This function allocates memory to argv and puts some strings in it. * It calls Note_The_Argv to hand you the argv and argc that are allocated. * \*---------------------------------------------------------------------------*/ extern void Hand_You_Argv( Note_Argv *Note_The_Argv ); /*---------------------------------------------------------------------------*\ * * This function takes in an argv and an argc and prints the contents * to standard output. * \*---------------------------------------------------------------------------*/ extern void Print_Argv( char *argv[], int argc ); #endif /* __C_MALLOC_FUN_H */ --------------61C26E7619C5 Content-Type: text/plain; charset=us-ascii; name="MakeTestMallocFun" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="MakeTestMallocFun" all: c_test_malloc_fun_proc test_malloc_fun_proc c_test_malloc_fun_proc: gcc -c -g c_malloc_fun.c test_malloc_fun_proc: gnatmake -g test_malloc_fun.adb -largs -lc c_malloc_fun.o clean: rm -f c_malloc_fun.o rm -f test_malloc_fun.o rm -f test_malloc_fun.ali rm -f test_malloc_fun rm -f b_test_malloc_fun.* --------------61C26E7619C5 Content-Type: text/plain; charset=us-ascii; name="test_malloc_fun.adb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="test_malloc_fun.adb" with Ada.Text_IO; use Ada.Text_IO; with Interfaces.C.Strings; procedure Test_Malloc_Fun is use type Interfaces.C.size_t; type Note_Argv_Ptr is access procedure ( Argv : in Interfaces.C.Strings.chars_ptr_array; Argc : in Interfaces.C.size_t ); pragma Convention( C, Note_Argv_Ptr ); procedure C_Hand_You_Argv( Note_Argv : in Note_Argv_Ptr ); pragma Import( C, C_Hand_You_Argv, "Hand_You_Argv" ); procedure C_Print_Argv ( Argv : in Interfaces.C.Strings.chars_ptr_array; Argc : in Interfaces.C.size_t ); pragma Import( C, C_Print_Argv, "Print_Argv" ); procedure My_Note_Argv ( Argv : in Interfaces.C.Strings.chars_ptr_array; Argc : in Interfaces.C.size_t ); pragma Convention( C, My_Note_Argv ); procedure My_Note_Argv ( Argv : in Interfaces.C.Strings.chars_ptr_array; Argc : in Interfaces.C.size_t ) is begin C_Print_Argv( Argv, Argc ); New_Line; Put_Line( "Argv'length is" & Integer'image( Argv'length ) & "." ); Put_Line( "Argv'first is" & Integer'image( Integer( Argv'first )) & "." ); Put_Line( "Argv'last is " & Integer'image( Integer( Argv'last )) & "." ); Put_Line( "Argc is" & Integer'image( Integer( Argc )) & "." ); New_Line; Put_Line( "Printing the Argv from Ada." ); Put_Line( "-------------------------------------------" ); -- -- Use this loop statement and it'll work just fine. for I in Argv'first .. Argv'first+Argc-1 loop -- -- Try these loop statement and you'll get a core dump. -- for I in Argv'range loop -- for I in Argv'first .. Argv'last loop Put_Line ( "Argv(" & Integer'image( Integer( I )) & " ) is """ & Interfaces.C.Strings.Value( Argv( I )) & """" ); end loop; Put_Line( "-------------------------------------------" ); end My_Note_Argv; begin C_Hand_You_Argv( My_Note_Argv'access ); end Test_Malloc_Fun; --------------61C26E7619C5--