www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - passing string[] to C

reply Charles D Hixson <charleshixsn earthlink.net> writes:
I hope this is trivial, but I haven't been able to figure out 
how I'm supposed to pass an array of strings to C.  I thought 
I had it solved, as everything looks right when I test the 
parameters, but at run time, well....
Here's my most recent trial (out of several):

The D routine:

import   std.conv;
import   std.cstream;
import   std.stdio;
import   std.stream;
import   std.string;

extern (C)  int   cGtkInit(int, char**);

class DTK
{  private  static   bool  _initialized   =  false;
    this()
    {  int   i  =  0;
       writefln ("DTK initializing");
       if (!initialized)
                 _initialized =(cGtkInit(0, null) != 0);
       if (!initialized)writefln  ("initialization failed");
    }
    this(string[] args)
    {  char*[]  argPs;
       argPs.length   =  args.length + 1;
       argPs.length   =  0;
       foreach  (arg; args)
       {  argPs ~= toStringz(arg);   }

       writefln ("next step is C");
       if (!initialized)
             _initialized   =
                 (cGtkInit   (args.length, argPs.ptr) != 0);
       if (!initialized)writefln  ("initialization failed");
    }

    bool  initialized()  {  return   _initialized;  }
}

The C routine:
#include <stdlib.h>
#include <stdio.h>

int   cGtkInit (int argc, char** argv)
{  int   i, j;
    printf   ("cGtkInit before initialization\n");
    printf   ("argv[%d] = \n", argc);
    printf   (".1......................................\n");
    for   (i = 0;  i < argc;   i++)
    {  printf   ("\t%d : ", i);   fflush(stdout);
       for   (j = 0;  j < 256; j++)
       {  if (argv[i][j] != 0)
          {  printf   ("%c", argv [i][j]);
             fflush(stdout);
          }
          else
          {  printf   ("\n");
             break;
          }
       }
       printf   (".2......................................\n");
       printf   ("\t%d : %s\n", i, argv [i]);
    }
    printf   (".3-------------------------------....\n");
    gtk_init (argc, argv);
    printf   ("cGtkInit after initialization\n");
    return   1;
}

Yielding at execution time:
Hello World!
screen variable declared.
next step is C
cGtkInit before initialization
argv[1] =
.1......................................
         0 : ./scribble
.2......................................
         0 : ./scribble
.3-------------------------------....
Segmentation fault
Apr 01 2008
parent Charles D Hixson <charleshixsn earthlink.net> writes:
Charles D Hixson wrote:
 I hope this is trivial, but I haven't been able to figure out how I'm 
It was trivial. Once I imported the correct header file into the C code, things started working. (Well...producing useful error messages.)
 Here's my corrected trial (severely edited.):
 
 The C routine:
 #include <stdlib.h>
 #include <stdio.h>
#include <gtk/gtk.h>
 
 int   cGtkInit (int argc, char** argv)
...
    printf   (".3-------------------------------....\n");
//> gtk_init (argc, argv); gtk_init (&argc, &argv);
    printf   ("cGtkInit after initialization\n");
    return   1;
 }
 
 Yielding at execution time:
Hello World! screen variable declared. next step is C cGtkInit before initialization char*[1] argv = .1...................................... argv [0] : './scribble' .2...................................... argv [0] : "./scribble" .3-------------------------------.... cGtkInit after initialization screen variable initialized. Screen initialized in routine amain gtk_init (&argc, &argv);
Apr 02 2008