comp.lang.ada
 help / color / mirror / Atom feed
* char **'s coming into Ada
@ 1997-03-14  0:00 Brett Kettering
  1997-03-16  0:00 ` Robert Dewar
  0 siblings, 1 reply; 2+ messages in thread
From: Brett Kettering @ 1997-03-14  0:00 UTC (permalink / 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--





^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: char **'s coming into Ada
  1997-03-14  0:00 char **'s coming into Ada Brett Kettering
@ 1997-03-16  0:00 ` Robert Dewar
  0 siblings, 0 replies; 2+ messages in thread
From: Robert Dewar @ 1997-03-16  0:00 UTC (permalink / raw)



Brett Kettering is trying to pass pointers to unconstrained arrays
directly from C to Ada, and asks

<<1) Am I doing something wrong here that I can't get the attributes of
the array?>>

yes, you are doing something wrong, this cannot possibly be expected 
to work automatically, since there is no bounds information on th C
side.





^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1997-03-16  0:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-03-14  0:00 char **'s coming into Ada Brett Kettering
1997-03-16  0:00 ` Robert Dewar

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