comp.lang.ada
 help / color / mirror / Atom feed
From: Brett Kettering <brettk@llnl.gov>
Subject: char **'s coming into Ada
Date: 1997/03/14
Date: 1997-03-14T00:00:00+00:00	[thread overview]
Message-ID: <332995FC.8B0@llnl.gov> (raw)


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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#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--





             reply	other threads:[~1997-03-14  0:00 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-03-14  0:00 Brett Kettering [this message]
1997-03-16  0:00 ` char **'s coming into Ada Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox