On Thu, 2004-09-23 at 16:04, Nick Ing-Simmons wrote: > Scott T. Hildreth <[EMAIL PROTECTED]> writes: > >Hello Nick, > > > > Sorry to send this to you directly, but I hopping to get a > >explanation soon. I sent this to the perl-xs list, but my post > >is not showing up. This happens with the DBI-users as well, I > >will post a question or reply and it will show up hours later. > >If I post to DBI-Dev, it shows right up...not sure what the problem > >is. Anyway I would appreciate any help here. > > > > > >On Thu, 2004-09-23 at 09:13, Scott T. Hildreth wrote: > >> Hello, > >> > >> I've seen this posted before, but I'm not sure what the answer is. > >> I have an XS interface to a 'C' library, which I used h2xs to create. > > Personally I don't use h2xs. > (I was writing XS before it existed and early versions were very weak, > never got round to using it since.)
I use it for creating the dirs, and creating the interface to funcs declared in the .h file. I usually add and change code, but it is a good start, for me. > > >> One of the functions takes argc & argv parameters. The h2xs created > >> argv as a char **, which is obviously correct. > > If you say so > const char ** > is possibly clearer about direction. Possibly, the parse routine that is called from this library, has the programs argc, argv sent as the inputs. It ultimately uses getop to parse the options. I don't remember if getopt alters the argv array. If not const char ** would be better declaration. Is that what you meant? > > > >When I run make test > >> which is loading the module, it dies because XS_unpack_PtrPtr() is > >> undefined. I see the typemap file in ExtUtils is defining char ** as > >> a T_PACKEDARRAY and so XS_unpack_$ntype($arg) gets created. > > Well $arg will become the SV that is being passed and $ntype > has become PtrPtr apparently. > > > >Where is > >> this? > > Not in the perl sources for a start (I just grep'ed them). I did the same. > > >>Is it a function or a macro? Do I need to implement it? > > I think h2xs expects you to implement it - but I wouldn't. > > >>I saw > >> the posting to packing a char ** on to the stack. Do I need to do the > >> opposite? > > I don't think going the route h2xs has suggested is the right way to go. > It isn't very perlish to pack strings or even pass an array ref. > For example perl's system() takes a list of strings. > > When faced with something taking argc/argv I usually code something > to work like system() does; like this: > > int > SomeFunc(...) > CODE: > { > char **argv; > int i; > Newz(42,argv,items+1,char *); // one more than we need so terminating NULL > for (i = 0; i < items; i++) { > argv[i] = SvPV_nolen(ST(i)); // Init strings > } > RETVAL = SomeFunc(items,argv); // Call the C function > Safefree(argv); // Free the array > } > OUTPUT: > RETVAL > > You could do something similar that expected an incoming array ref > and itterated over array elements rather that items/ST(i). > > Of course if char ** is for output parameters that is wrong, > but in such a case I would probably want a list return > so would do the PPCODE thing. > > If above doesn't help then I would like to see: It does help, thanks! > - The C declaration of the function Here it is anyway, CLI *cli_parse(int argc, char **argv ); > > - the XS code from h2xs CLI * cli_parse(argc, argv) int argc char ** argv ...I changed that to 'char * &argv' > - The C code after xsubpp > With 'char * &argv', XS(XS_Allant__Tools__Cli_cli_parse); /* prototype to pass -Wmissing-prototypes */ XS(XS_Allant__Tools__Cli_cli_parse) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Allant::Tools::Cli::cli_parse(argc, argv)"); { int argc = (int)SvIV(ST(0)); char * argv = (char *)SvPV_nolen(ST(1)); CLI * RETVAL; RETVAL = cli_parse(argc, &argv); ST(0) = sv_newmortal(); sv_setref_pv(ST(0), "CLIPtr", (void*)RETVAL); } XSRETURN(1); } With 'char ** argv', XS(XS_Allant__Tools__Cli_cli_parse); /* prototype to pass -Wmissing-prototypes */ XS(XS_Allant__Tools__Cli_cli_parse) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Allant::Tools::Cli::cli_parse(argc, argv)"); { int argc = (int)SvIV(ST(0)); char ** argv = XS_unpack_charPtrPtr(ST(1)); CLI * RETVAL; RETVAL = cli_parse(argc, argv); ST(0) = sv_newmortal(); sv_setref_pv(ST(0), "CLIPtr", (void*)RETVAL); } XSRETURN(1); }