Re: Manipulating the perl stack from within a non-XSUB function
Alan Burlison [EMAIL PROTECTED] writes: Nick Ing-Simmons wrote: Ah, oops sorry I missed the PPCODE vs CODE issue. (The machine-level programmer in me distrusts moving the stack back before one is finished with it so for that reason I seldom use PPCODE.) I'm pushing variably sized lists onto the stack, for example when called in a scalar context the routine returns a single value, and a list when called in a list context (or an empty list on error). According to perlxs if you are going to do that sort of thing you need to use PPCODE instead of CODE: Isn't that correct? Yes or do your own SP twiddling. Guts of what Tk uses is: SV **args = ST(0); int offset = args - sp; if (count items) { EXTEND(sp, (count - items)); } /* Now move 'args' to 0'th arg position in current stack */ args = sp + offset; if (count) { int i = count; while (i-- 0) { args[i] = some_sv(); } } PUTBACK; XSRETURN(count); PPCODE bit me once when C code called back into perl after PPCODE had moved back SP, then tried to use ST(N) after perl had returned back to the XSUB - and of course it had been overwritten by then. Not that Tk is a perfect model of how to do it - it has its own particular problems. (Perls stack is passed as args to core tk, which can call callbacks and hence back into perl.) -- Nick Ing-Simmons
Re: Manipulating the perl stack from within a non-XSUB function
Alan Burlison [EMAIL PROTECTED] writes: Nick Ing-Simmons wrote: if (mystp = getmystructbyid(id)) { pushret_mystruct(mystp); return; } else { XSRETURN_EMPTY; } This isn't quite right (well, actually it doesn't work :-) On examining the code generated by xsubpp, it does a SP -= items; at the very beginning of the generated code. Ah, oops sorry I missed the PPCODE vs CODE issue. (The machine-level programmer in me distrusts moving the stack back before one is finished with it so for that reason I seldom use PPCODE.) This of course only updates the local copy of SP, so when the called routine does a dSP it gets the value of the SP before the subtraction. To fix it you simply need to PUTBACK; before the call to pushret_mystruct. Yes. See, because of your help I now really *do* understand what is going on :-) Excellent. -- Nick Ing-Simmons
Re: XS and header files
Nathan Torkington [EMAIL PROTECTED] writes: Is there some reason that xsubpp couldn't automatically add the #include "EXTERN.h" #include "perl.h" #include "XSUB.h" lines which are automatically put there by h2xs? Do some XS files not need them? Surely not. It just seems odd to me. Their placement relative to other headers can be absolutely vital. I can be essential to set things up before "perl.h" includes the known universe. -- Nick Ing-Simmons
Re: Dynamically loading the shared objects
Soumen Das [EMAIL PROTECTED] writes: Hi, I am wrapping a few C++ API's with perl xs on Solaris. The C++ API's dynamically load a few shared objects(these shared objects are not linked). With a small C++ test app and using the same C++ API's, this happens successfully. But when I do the same with the Perl wrapped API's it fails to dynamically load the shared object. Any reasons why this would happen only thru the Perl program which wraps the C++ API's ? What does 'truss' show as happening ? Guess: With a stand alone C++ app. the loaded shared objects get to see the symbols in the application - the executable. When you load shared objects into a perl extension which is itself loaded the "exectuable" is perl itself, so the second-level loadables see that and not the thing with the API. There are various work rounds: - link the perl extension with the libraries explicitly. - re- dlopen() the externsion.so with RTLD_LOAD_GLOBAL to make its symbols available to loadables. - statically link the extension to a perl. I am sure about my LD_LIBRARY_PATH. LD_LIBRARY_PATH is a bad idea in general. Also tried using the PERL5LIB environment variable. Regards, Soumen -- Nick Ing-Simmons
Re: Return Value comparison for const wchar_t*
Manisha Mirajkar [EMAIL PROTECTED] writes: Hi, I am passing a const wchar_t* from a function MyFunc() in my XS file. I have a custom typemap for const wchar_t* : const wchar_t * T_WCHAR INPUT T_WCHAR $var = ($type)SvPV_nolen($arg) OUTPUT T_WCHAR sv_setpv((SV*)$arg, (char *) $var, wcslen($var)*sizeof($type)); A wide character is just that - _wide_ there will be a lot of nulls in the "string". In my perl script I want to do a string comparison where the first letter is say 'h'. My perl script is - $Name = Config::MyFunc(); print $Name; if($Name =~ m/^h/) { do something } The clean way to do this in perl (IMHO) is to use perl5.6+ and UTF-8 encode your wide characters. The pattern would have to be (Assuming 32-bit big-endian wide character): $name =~ m/^\0\0\0h/ If little endian and 16-bit that would be /^h\0/ - which might have worked for a while. The $Name has a correct value as I see when I print it. Your terminal is probably ignoring the '\0's But, the comparison does not work! The same thing works if the function returns a const char* which in my typemap is - const char* T_PV Is my typemap for const wchar_t* incorrect ? You cannot use perl's string operators on wide chars like that, they will work if you tell them about the nulls. If yes, then how do I get a proper value when I print, and what could be done so that the comparison works? Unicode, perl5.6+ Thanks, Manisha -- Nick Ing-Simmons
Re: How do I include a .h file with my XS module distribution?
David M . Lloyd [EMAIL PROTECTED] writes: I want to install a C header file into the same place that perl's header files are kept when my XS module is installed. Has anyone ever done that? Yes. I can't find anything in MakeMaker's manpage that I can use for that... in fact, I can't find anything that will even let me install arbitrary files! If you have in your Makefile.PL package MY; sub post_initialize { my ($self) = @_; my $ddir = $self-catdir('$(INST_ARCHLIBDIR)','SubDir'); my $src = $self-catfile('somedir','SomeFile.h'); next unless -f $src; $self-{PM}-{$src} = $self-catfile($ddir,'SomeFile.h'); } Then your .h file will get installed along with the .pm files. Thanks... - D [EMAIL PROTECTED] -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: How to pass file handles?
Steven N . Hirsch [EMAIL PROTECTED] writes: On Thu, 29 Nov 2001, Forrest Cahoon wrote: Lack of documentation is driving me nuts! All the references I can find point me to perlapio for information about dealing with Perl I/O inside of XS functions. That's nice ... now how do I get one into or out of XS code? That I can't find anywhere. In theory (at least in perl5.7.*) the default typemap should have an entry for PerlIO * So : PerlIO * ThingThatReturnsOne(...) and ThingThatExpectsOne(PerlIO *f) should just work - what gets messy is that that If I create an IO::File object in perl and pass it into my XS function, can I just cast the SV * into a PerlIO * and work with that? Is that what I'm supposed to do? No. In general the SV will be a reference-to-a-glob. You need to dereference it and then use GvIO to get the IO - sv_2io() does that for you, you then and then IoIFP() to get the PerlIO * - unless you want IoOFP of course. - more indirections that one could possibly want :-( For INPUT $var = IoIFP(sv_2io($arg)) If I create a PerlIO * in my XS code, do I pass it back to perl as an SV *? Is it blessed in some appropriate way? What would it be, IO::Handle? The default typemap creates a blessed reference to a new glob in the XS's package and then uses a messy call to the internals to import the PerlIO * I also can't find any way to search the perl-xs archives ... I suspect this has been covered many times already. Sorry about the probable repitition. I really appreciate any help I might receive. That makes two of us. I couldn't find so much as a shred of documentation on this. Even some example code would be better than nothing. Steve -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: How to pass file handles?
Forrest Cahoon [EMAIL PROTECTED] writes: I'm using 5.6.1 (on Linux) and may have to run on 5.00503 (on VMS) as well: are these things that I can add to my local typemap? They should be there on older perls too - but prior to 5.7 a PerlIO * is really as FILE *. Or should I stay away from PerlIO and use the former interface (which I also have no clue about)? I had really hoped to use the latest and greatest, but I have to stick to what people are really using in production environments. PerlIO * has been there since 5.003_02 If I create an IO::File object in perl and pass it into my XS function, can I just cast the SV * into a PerlIO * and work with that? Is that what I'm supposed to do? No. In general the SV will be a reference-to-a-glob. I thought IO::File was going to be the new way in Perl and we were going to do away with all those ugly \*FOO -style parameters. Is that not correct? IO::File is considered by some to be an unnessary extra abstraction. perl5.7.* can do : open(my $fh,...) and create the glob-ref as required itself. Is IO::File just a blessed globref, or what? Yes it is. If I do want to pass an IO::File object to my XS function, do I need to do something different here? No. Perl level file handles are (in perl5) globs (strictly the IO part of the glob but that is not really an issue here). Deep inside is a PerlIO * - which in older perls is #define-d to FILE *. You need to dereference it and then use GvIO to get the IO - sv_2io() does that for you, you then and then IoIFP() to get the PerlIO * - unless you want IoOFP of course. - more indirections that one could possibly want :-( For INPUT $var = IoIFP(sv_2io($arg)) OK, I think I actually understand this (scary!). So does sv_2io() get a FILE * from my SV * that was passed into XS as a globref and IoIFP() turn that FILE * into a PerlIO * ? It fished out a PerlIO *. On older perls IoIFP _is_ a FILE *. On perl5.7.* PerlIO * is a structure of our own. If I create a PerlIO * in my XS code, do I pass it back to perl as an SV *? Is it blessed in some appropriate way? What would it be, IO::Handle? The default typemap creates a blessed reference to a new glob in the XS's package and then uses a messy call to the internals to import the PerlIO * This is the 5.7.x typemap, right? (I guess in earlier Perls I'm not gonna be using PerlIO *, or should I?) You should use PerlIO * unless you have something 5.003_01 or earlier, and I hope you don't. Unless you have perl5.7 the PerlIO * will _be_ a FILE * but you should pretend you don't know that and use the PerlIO_x() functions. That way when perl5.8 hits the streets you will be ready. And what is the glob reference blessed to ... IO::Handle, as I guessed earlier? It is blessed into your XS's package. Your perl's standard typemap should have entries for these things by one name or another. I also can't find any way to search the perl-xs archives ... I suspect this has been covered many times already. Sorry about the probable repitition. I actually did find searchable archives at http://www.xray.mpe.mpg.de/mailing-lists/perl-xs/ but I still didn't find any useful discussion (for a clueless person like myself) of this topic. I really appreciate any help I might receive. Yeah, I meant that. Thanks, Nick! Forrest Cahoon not speaking for merrill corporation -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Makefile.PL, ActiveState and MSVC5.0
Tye McQueen [EMAIL PROTECTED] writes: Excerpts from the mail message of Billy Patton: ) ) I'm trying to get my XS, written and used on a SUN, ) to transport to my pc at home. DOes anyone have ) an example Makefile.PL for winders98, MSVC5.0 and ) ActiveState perl 5.6* The Makefile.PL should be completely independant of operating system, compiler, etc. Note that building Perl modules under Windows98 sucks because command.com sucks (doesn't support and ). If you can upgrade to WinNT, Win2K, WinXP, then you'll have better luck. All true. Also if I recall correctly MSVC5.0 (without service packs) is a bit buggy - one must not use optimization. Alternately, you can try to find a replacement shell (sorry, I don't have a recommendation) or work around the several problems that you'll likely run into (usually by patching things in ExtUtils). Tye -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Building an array of objects
Mike Wong [EMAIL PROTECTED] writes: Hi all, I have a data structure that is a linked list. In my XSUB, I'd like to traverse that linked list and return the list as an array of objects. FWIW you are returning a list of objects in the perl sense, that is you are pushing them on the stack, not putting them in an AV. Here's some of my code so far: void tracks( self ) llist_node *self PREINIT: llist_node *node; PPCODE: node = self; while( node != NULL ) { EXTEND(SP, 1); PUSHs( ); -- What goes here? node = node-next; } I hope you can see the part where I have no clue as to what to do :^). llist_node * is defined in my typemap as an O_OBJECT and returns a blessed scalar. O_OBJECT seems to be a custom typemap entry - which is fine. What does your typemap do with a list_node * to convert it to an SV ? presumably it does something like: sv_setref_iv(sv, YourClass, node); So the loop should look like: while( node != NULL ) { SV *sv = sv_newmortal(); sv_setref_iv(sv, YourClass, node); XPUSHs(sv); node = node-next; } Replace sv_setref_iv with whatever the OUTPUT section of your typemap entry does. I've tried: PUSHs( sv_2mortal( node )); to no great success. I've run about a dozen Google searches in addition to the half-dozen or so searches on the archives of this list. Couldn't find this kind of information. Can someone please help? Thanks in advance! - m. -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: global
Billy Patton [EMAIL PROTECTED] writes: How di I export a c global variable into perl?? In c I have int XYZ = 0; How do I get this into perl WO having to write a function. You don't. EXPORT qw ( XYZ ); Presumably you mean @EXPORT = qw($XYZ); How you map that depends on whether you want C side changes to the global to magically update the perl variable or if it is really a constant. If you want C changes to apear in perl you need to use tie (or magic in mg.h sense) to cause perl to look at C variable every time - this is messy. If it really a constant then it is best to #define a function: #define ACCESS_XYZ() XYW and MODULE ... PREFIX = ACCESS_ int ACCESS_XYX() THis seems to be missing something. -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Basic question
Medi Montaseri [EMAIL PROTECTED] writes: So the fact that XS can parse C header files is limited to bunch of symbolic constants and CPP directives? How about struct definitions and such. xsubpp does not parse C header files _at all_. It just copies XS verbatim to the .c file till it sees 1st MODULE line, then processes each paragraph according to its own syntax. There is an h2xs tool which tries to parse .h and generate .xs which would export that to perl. -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Debugging c++ shared libraries
Bill Moseley [EMAIL PROTECTED] writes: At 05:30 PM 05/20/02 +0100, Nick Ing-Simmons wrote: If I copy the .xs code into a main {} block and build a stand-alone C program it works fine everyplace. Static linking the extension into perl should also work. Hum, not exactly sure what you are suggesting. My work with xs has been rather straight forward in the past, following h2xs's setup and filling in the blanks. I haven't had such a difficult situation before. But this is suppose to be a CPAN module, so I would hope that it could be built like a normal module. If there's a but in aspell/pspell I could supply a patch, but asking people to rebuild perl might be much. Kind of sounds like I'm out of options. Is that your thinking? It works on linux/solaris and probably elsewhere with modern C++ systems. Anything which mixes C++, exceptions and dynamic loading is not going to be as portable as perl (which is just ANSI C). Thanks very much, -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Debugging c++ shared libraries
Bill Moseley [EMAIL PROTECTED] writes: At 10:03 PM 05/20/02 +0100, Nick Ing-Simmons wrote: It works on linux/solaris and probably elsewhere with modern C++ systems. What it are you referring to? My module? Yes. Anything which mixes C++, exceptions and dynamic loading is not going to be as portable as perl (which is just ANSI C). What's weird is that my two linux systems are very similar. I might expect it to not work on a different platform, but not on two different linux systems. My SuSE 6.2: Perl 5.6.0 built from source, gcc version 2.95.3 20010315 (release) My Debian Woody is Perl 5.6.1 debian package, gcc version 2.95.4 20011002 (Debian prerelease) GNU gdb 2002-04-01-cvs I am always sceptical about distributions prerelease or patched versions. I am not really a C++ expert but I lurk on GCC list and so know that exceptions were/are a little fluid in their implementation. It would be easy for an ad. hoc. prerelease to have grabbed an inconsistent set of patches. I installed the aspell/pspell code from source on all machines. So it's a bit odd that it works on my SuSE machine but aborts on the Debian. Not a lot of difference. My opinion is that SuSE tends to be better quality controlled than even RedHat and that Debian does a good job at getting latest stuff. Could be a missing library, I suppose, but I don't know how to detect this. (My use of) gdb, strace and ltrace have not helped. And I just don't know what to thing about PERL_DL_NONLAZY. I thought all that did was set a flag (RTLD_NOW) on dlopen calls made by perl. So it seems odd that would effect the c++ code at all. I just now build Perl 5.7.3 on Debain and it's exactly the same problem. Which is good ;-) (at least from the perl point of view) and points at it being a Debian problem not a perl-xs problem. This works: PERL_DL_NONLAZY=0 /home/moseley/perl/ithread/bin/perl5.7.3 -I'blib/lib' -I'blib/arch' t/test.t This does not (e.g. Aborted) What PERL_DL_NONLAZY=1 does is insist that all the symbols your loadable needs are resolved - or it aborts. It should report which symbol it thought was missing. It may be that on non-ELF systems C++'s desire for weak refs (I concept I don't fully understand myself) confuses dynaloader into thinking you _need_ something you don't really. The PERL_DL_NONLAZY=0 case may work if particular .t file does not call the missing function. If dlopen() doesn't report the missing function then using nm on the .so file created from your XS and grep'ing for ' U ' will list symbols that are needed you can then compare those exported by perl executable and see what is missing. PERL_DL_NONLAZY=1 /home/moseley/perl/ithread/bin/perl5.7.3 -I'blib/lib' -I'blib/arch' t/test.t -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: perlcc
Billy Patton [EMAIL PROTECTED] writes: Any of you had any experience using perlcc (5.005_2) The perlcc in a perl that old does not work very well. Actually none of them work very well. I have never used it in production. to get a perl script that uses several .so files stored in the auto directories? DOes perlcc use the use lib stuff to find everything it needs? That is the theory. Does this take long? Yes - it builds one HUGE function and then compiles for optimization GCC in particular gets over excited about the possibilities for optimizing it. SHould there be so many : No. Some later perlccs are a bit better. Making C(compatabut.p.c) for compatabut.p! /apps/perl5.005/bin/perl -I/apps/perl5.005/lib/5.00502/sun4-solaris -I/apps/perl5.005/lib/5.00502 -I/apps/perl5.005/lib/site_perl/5.005/sun4-solaris -I/apps/perl5.005/lib/site_perl/5.005 -I. -MO=CC,-ocompatabut.p.c compatabut.p compatabut.p syntax OK Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 284. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 288. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 284. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 288. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 284. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 288. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 284. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 288. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 284. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 288. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 284. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 288. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 284. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 288. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 811. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 811. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 284. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/CC.pm line 288. Use of uninitialized value at /apps/perl5.005/lib/5.00502/sun4-solaris/B/C.pm line 602. substcont: op = LOGOP (0x2d0bc0) pp_substcont, pmop = PMOP (0x2cc740) pp_subst pmopsym = (OP*)pmop_list[46] substcont: op = LOGOP (0x2c9fa0) pp_substcont, pmop = PMOP (0x2cc500) pp_subst pmopsym = (OP*)pmop_list[47] substcont: op = LOGOP (0x2d0d40) pp_substcont, pmop = PMOP (0x2cc600) pp_subst pmopsym = (OP*)pmop_list[48] substcont: op = LOGOP (0x2d08c0) pp_substcont, pmop = PMOP (0x2cc540) pp_subst pmopsym = (OP*)pmop_list[49] substcont: op = LOGOP (0x2d0a60) pp_substcont, pmop = PMOP (0x2cc640) pp_subst pmopsym = (OP*)pmop_list[50] substcont: op = LOGOP (0x2d0940) pp_substcont, pmop = PMOP (0x2cc5c0) pp_subst pmopsym = (OP*)pmop_list[51] and there's much more that this -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Problem with PUSHMARK, and call_sv in callbacks
Scott Witzke [EMAIL PROTECTED] writes: I am having problems with PUSHMARK, call_sv, and other simular calls. Each seg faults. I am using perlcall as a template with ASPerl 5.6.1 build 631 on Solaris. Superficially okay. Does Solaris ASPerl do threads or Multiplicity? If so there are some THX things missing. static SV * callback = (SV*)NULL; static variable is not thread safe. Most likely cause of your segfaults is that the SV you saved a pointer to in that static has been free'd or used for something else since you put it there. static void C_callback( first_string ) Either C_callback( pTHX_ char *first_string ) char *first_string; { dSP; or add dTHX; about here PUSHMARK( SP ); XPUSHs(sv_2mortal(newSVpv( first_string, 0 ) ) ); PUTBACK; call_sv( callback, G_DISCARD ); } ___ GO.com Mail Get Your Free, Private E-mail at http://mail.go.com -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: SV* reference from C to Perl
Amar Deep Singh [EMAIL PROTECTED] writes: Hi I am calling a C subroutine from Perl. The *argv_ptr if the global @ARGV is perl. I am passing the pointer to this to the C which does some manipulations and removes some of the arguments in @ARGV. But it seems the values returned are not the same which I want. Any idea how I can push the values of args_av back into argv_ptr. I am pushing back the values in args_av but its not working. Any idea if I am missing something. In simple words I want the modified values of c_args to be put into @ARGV, which is nothing but the pointer argv_ptr @ARGV is an AV not just an SV ** - you need to get the AV and call av_push() etc. to keep length in sync. Thanks Amar Here is the code in xs. which i call from Perl as return _Initialise($config, $0, \@ARGV); = int D_Initialise(config, appname, argv_ptr) Configuration config char *appname SV *argv_ptr CODE: { int argc, i, str_length; char **c_args; char *arg; SV *tmpSV; AV *args_av, *ret_args; /* dereference the argv */ args_av = (AV*) SvRV(argv_ptr); /* get the number of arguments */ argc = av_len(args_av) + 1; /* allocate enough memory */ c_args = (char **) malloc((argc + 1) * sizeof(char *)); /* copy the appname into the c_args array */ c_args[0] = (char *) malloc((strlen(appname) + 1) * sizeof(char)); /* copy the contents of the argv ref */ for(i = 0; i argc; i++) { /* get the string */ tmpSV = av_shift(args_av); arg = (char *) SvPV(tmpSV, str_length); c_args[i + 1] = (char *) malloc((str_length + 1) * sizeof(char)); strcpy(c_args[i + 1], arg); } /* now call the proper Initialise */ RETVAL = Initialise(config, c_args, argc); /* put the arguments back */ for(i = 0; i argc; i++) { av_unshift(args_av, 1); av_store(args_av, i, (SV *) newSVpv(c_args[i], 0)); } } OUTPUT: argv_ptr RETVAL = -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: debugging embedded perl
Krishna Kumar Rangan [EMAIL PROTECTED] writes: Hi Sorry for emailing directly. I had posted this question on comp.lang.perl.misc and comp.lang.perl.modules, but did not get any help. I saw your replies to questions related to the one I have and thought of asking you. I want to debug a perl script run by a perl interpreter embedded in a C++ application. The perl script (sample.pl) uses a module named 'foo' and foo.pm uses an another module 'bar'. Both foo and bar modules are linked to C++ libraries. When sample.pl is invoked from the command line, bar.pm finishes loading successfully (bar.so is successfully loaded) and foo.pm load fails elsewhere. I suggest you fix that first. However, when the script is interpreted from the C++ application, loading bar.pm fails. The error message says that there is an error in line 27 in foo.pm - and line 27 contains 'use bar'. I am assuming that bar.so load fails. Please: A. copy/paste exact error messages - all of them not just the last line. B. Run perl -V and attach its output. My questions are - Is it possible to get an error message that is little more detailed? perl_parse documentation is not found anywhere; I am calling the routine with the arguments (perl_interp, NULL, argc, argv, NULL) with argv[1] = sample.pl. nm bar.so, shows these undefined symbols which did not cause any problems when sample.pl is invoked frm command line. ... U PL_curpad U PL_markstack_max Those are symbols in libperl.a (or perl5X.dll or ...) On Solaris/Linux etc. such symbols are resolved against the root executable, but not against other loadables. For some reason your C++ root is not exporting those symbols. Please show us exactly how the C++ application was linked. -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Calling constructor with xsub
Bill Moseley [EMAIL PROTECTED] writes: PUSHMARK; XPUSHs(swish_handle_sv); XPUSHs(query_sv); PUTBACK; call_method(new,G_SCALAR); SPAGAIN; search_object_sv = POPs; I think that last line is where I'm going to get stuck. See below. Which suggests that using this signature would be better: SW_SEARCH new(CLASS, swish_handle, optional_string ) char *CLASS SV *swish_handle As it avoids the need to back-convert the SW_HANDLE to an SV. But in that SWISH::API::Search::new function I need to pass SW_HANDLE into my C code, so seems like I'd need to pass around SW_HANDLE. You are still passing it around. You are just not un-packing it in the outer call. But maybe I'm misunderstanding your example. Let's see if I'm following. Say I will create two objects. my $handle = SWISH::API-new( index.file ); Fine. So now $handle is an SV * with a SW_HANDLE hidden inside. # Create a search object based on the handle object. my $search = SWISH::API::Search-new( $handle, $query ); These constructors seem simple enough. MODULE = SWISH::APIPACKAGE = SWISH::API SW_HANDLE new(CLASS, index_file_list ) char *CLASS char *index_file_list CODE: /* SwishInit is in the C library */ RETVAL = SwishInit( index_file_list ); OUTPUT: RETVAL So that new returns a SW_HANDLE - fine. MODULE = SWISH::APIPACKAGE = SWISH::API::Search SW_SEARCH new(CLASS, swish_handle, query ) char *CLASS SW_HANDLE swish_handle /* So we are going to find the SW_HANDLE inside the passed arg */ char *query CODE: /* New_Search_Object is in the C library */ RETVAL = New_Search_Object( swish_handle, query ); OUTPUT: RETVAL Now, since you always need to pass a handle to create a search object, I decided to make the API look more like: my $handle = SWISH::API-new( index.file ); #my $search = SWISH::API::Search-new( $handle, $query ); my $search = $handle-New_Search_Object( $query ); So back in the SWISH::API package: Not quite right - see non-quoted bits added. SV * New_Search_Object(self, query) SV * self; /* we want an SV for the handle so ... */ char *query/* If you had query as an SV too ... */ CODE: PUSHMARK; XPUSHs(sv_2mortal(newSVpv(SWISH::API::Search,18)); XPUHSs(self); /* ... we can pass the handle to new */ XPUSHs(sv_2mortal(newSVpv(query,0)); /* ... we could avoid convert to/from string */ PUTBACK; call_method(new,G_SCALAR); SPAGAIN; RETVAL = POPs; OUTPUT: RETVAL That throws me off a bit since SWISH::API::Search::new returns a SW_SEARCH object yet that returns a SV *. Which contains the SW_SEARCH hidden inside by the output typemap of the new XSUB. Another way to look at this is suppose you had written New_Search_Object as perl code - e.g. in your .pm file you could have had: package SWISH::API; sub New_Search_Object { my ($handle,$query) = @_; return SWISH::API::Search-new($handle,$query); } The modified XS code above is doing the same - calling the inner method but just using/returning SVs without looking inside. BTW, in my previous message I had a typemap of: TYPEMAP SW_HANDLE * O_OBJECT SW_SEARCH * O_OBJECT SW_RESULTS * O_OBJECT SW_RESULT * O_OBJECT But SW_* are already pointers to a structure so I can just use this. Correct? TYPEMAP SW_HANDLE O_OBJECT SW_SEARCH O_OBJECT SW_RESULTS O_OBJECT SW_RESULT O_OBJECT I apologize for being so lame at this stuff! ;) XS sometimes makes me feel like that guy on the cover of Extending and Embedding Perl... Thanks, -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Calling constructor with xsub
Bill Moseley [EMAIL PROTECTED] writes: I also realize that in my xsub there's no real point in calling SWISH::API::Search::new just to create the object as New_Search_Object can just call the C code to fetch the new struct returned as an object. I think I could do that directly with sv_setref_pv and avoid using call_method. I really don't need a new() method in the Swish::API::Seach package since it will never be called from perl. The details of using sv_setref_pv are a bit clowdy right now, but I intend to read a bit more as soon as I get some time. sv_setref_pv gives me a headache too. (FWIW most of my objects use sv_setref_iv as I store pointers to C/C++ objects in IV rather than PV - but you need to be consistent.) But what you are saying can (I think) be expressed as XS ;-) and so let normal typemap magic do the blessing Something like: MODULE = SWISH::APIPACKAGE = SWISH::API SW_SEARCH New_Search_Object(swish_handle, query) SW_HANDLE swish_handle char *query INIT: char *CLASS = SWISH::API::Search; CODE: RETVAL = New_Search_Object( swish_handle, query ) OUTPUT: RETVAL The INIT:/CLASS is just there so it is in scope (I hope) when typemap for OUTPUT does its thing to bless the object. -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: typemaps for vector... and other STL containers
Shinya Hayakawa [EMAIL PROTECTED] writes: Hi Ian, On Mon, 21 Oct 2002 19:57:34 + [EMAIL PROTECTED] wrote: I'm trying to write some interface routines to the Numerical Recipes library and want to be able to pass Perl arrays (or references) to C++ vector... objects, and vice versa. The xsubpp compiler doesn't support C++'s template facilities. We need to define typemaps for each template instance as follows: typedef vectorint IntVector; typedef vectorstring StringVector; IntVector T_INT_VETOR StringVectorT_STR_VECTOR With a little work I am sure we could avoid the typedef and have typemap just say vectorint T_VECTOR_INT vectorstring T_VECTOR_STRING INPUT T_INT_VETOR if (SvROK($arg) SvTYPE(SvRV($arg))==SVt_PVAV) { AV *avref = (AV*)SvRV($arg); int len = av_len(avref) + 1; for(int i = 0; i len; ++i) { SV **elem = av_fetch(avref, i, 0); if( elem == NULL ) $var.push_back(0); else $var.push_back(SvIV(*elem)); } } else Perl_croak(aTHX_ \$var is not an array reference\) The structure there is a feature of vector-ness. The only part that differs is the element to/from SV conversion. You cannot overload on return type unfortunately, so guts a generic T_VECTOR might look like template elemtype elemtype elem; sv_to_type(sv,elem); var.push_back(elem); The fun part of that is trying to devise a template scheme so that element types of int, char, long etc do SvIV () while char *, string etc. do SvPV and float, double to SvNV(). Might be easier just to have a set of overloaded functions: inline void sv_to_type(SV *sv,int elem){ elem = SvIV(sv) } inline void sv_to_type(SV *sv,double elem) { elem = SvNV(sv) } It probably makes sense (it often does IMHO) to make the typemap call a function - that function can be in C++ part of the .xs file and so be overloaded or templated in C++ way - but we need to find a way to get $elemtype in this fragment: T_VECTOR $elemtype dummy; sv_to_vector($arg,$var,dummy) By looking at the xsubpp code we _may_ be able to find a way to fish $elemtype out of vectorelemtype -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: embedded perl memory leak
, iLbound, i1, iIsOk = 1; SAFEARRAY *ps_SafeArray = V_ARRAY(ps_InVariant); VARIANTARG *ps_Variants; AV *pPerlArray = newAV(); SafeArrayGetUBound ( ps_SafeArray, 1, iUbound ); SafeArrayGetLBound ( ps_SafeArray, 1, iLbound ); SafeArrayAccessData ( ps_SafeArray, (void**)ps_Variants ); for ( i1 = iLbound; i1 = iUbound; ++i1 ) { VARIANTARG*ps_CurrVariant = ps_Variants[i1]; enum VARENUM eCurrType = (enum VARENUM) V_VT(ps_CurrVariant); if(eCurrType VT_ARRAY) { av_push ( pPerlArray, newRV_noinc ( PerlCreateCallArray ( my_perl, ps_CurrVariant, iIsOk ) ) ); } else { switch(eCurrType) { case VT_EMPTY: case VT_NULL: av_push( pPerlArray, newSVsv(PL_sv_undef) ); break; case VT_R8: av_push( pPerlArray, newSVnv(V_R8(ps_CurrVariant)) ); break; case VT_I4: av_push( pPerlArray, newSViv(V_I4(ps_CurrVariant)) ); break; case VT_BSTR: { char *pczValue = ScriptCmnNewCharFromBstr( V_BSTR(ps_CurrVariant) ); av_push( pPerlArray, newSVpv((char*)pczValue, strlen(pczValue)) ); ScriptDeleteCharFromBstr ( pczValue ); } break; default: iIsOk = 0; } } if ( !iIsOk ) break; } /* End for */ *piIsOk = iIsOk; return (SV*) pPerlArray; } / // /*Function: PerlProcessReturnValue*/ // static int PerlProcessReturnValue ( PerlInterpreter *my_perl, SV *pVal, VARIANTARG *ps_Result ) { int iIsOk = 1; svtype eValType = (svtype) SvTYPE(pVal); VariantClear( ps_Result ); switch( eValType ) { case SVt_NULL: break; case SVt_IV: case SVt_PVIV: if ( SvIOK(pVal) ) { V_VT(ps_Result) = VT_I4; V_I4(ps_Result) = SvIV(pVal); } else { iIsOk = 0; } break; case SVt_NV: case SVt_PVNV: if ( SvNOK(pVal) ) { V_VT(ps_Result) = VT_R8; V_R8(ps_Result) = SvNV(pVal); } else { iIsOk = 0; } break; case SVt_PV: { char *pczTemp; STRLEN iLength; pczTemp = SvPV(pVal,iLength); PerlMakeStringVariant( pczTemp, iLength, ps_Result ); } break; case SVt_PVAV: { AV *pArrayVal = (AV*) pVal; longiLength = av_len ( pArrayVal ), i; SAFEARRAY*pSafeArray = NULL; SAFEARRAYBOUNDdim[1]; dim[0].lLbound = 0; dim[0].cElements = iLength+1; pSafeArray = SafeArrayCreate(VT_VARIANT, 1, dim); { SV **ppElementValue; VARIANTARGs_VariantValue; VariantInit ( s_VariantValue ); for ( i = 0; i = iLength; ++i ) { VariantClear ( s_VariantValue ); (ppElementValue) = av_fetch( pArrayVal, i, 0 ); iIsOk = PerlProcessReturnValue ( my_perl, *ppElementValue, s_VariantValue ); if ( iIsOk ) { SafeArrayPutElement( pSafeArray, i, (void*) s_VariantValue ); } else { break; } } VariantClear ( s_VariantValue ); if ( iIsOk ) { V_VT(ps_Result)= VT_ARRAY | VT_VARIANT; V_ARRAY(ps_Result) = pSafeArray; } else { SafeArrayDestroy( pSafeArray ); } } } break; case SVt_RV: { SV *pDerefVal = SvRV( pVal ); iIsOk = PerlProcessReturnValue ( my_perl, pDerefVal, ps_Result ); } break; default: iIsOk = 0; } return iIsOk; } -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: perl_call_pv - call_pv
Bill Moseley [EMAIL PROTECTED] writes: I have an xsub that doesn't work under 5.00503 because is uses call_pv instead of perl_call_pv. I must of missed something somewhere -- what's the method to make the code work in different versions of perl? I added: #ifndef call_pv # define call_pv(i,j) perl_call_pv(i,j) #endif If you ever have threads or multiplicity that needs to be #ifndef call_pv # define call_pv(i,j) perl_call_pv(aTHX_ i,j) #endif and you need to have a conext arg in scope - i.e. a dTHX to fetch it or a pTHX to pass it in to the caller (XSubs have one to hand). It was to hide all that noise that call_pv() was invented. I consider it a mixed blessing - its magical calling of get context can become resource hog. Doing it the old way with perl_call_pv() and explicit aTHX_ not only works on older perl's but can give better code on modern ones. (The PERL_NO_GET_CONTEXT mentioned in another thread turns off the magical fetching and requires you to have dTHX / pTHX but still supplies the aTHX as required.) dTHX - declare THread conteXt. pTHX - prototype THread conteXt. aTHX - actual/argument THread conteXt. -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Accessing the perl stack from C
Aldo Calpini [EMAIL PROTECTED] writes: Nick Ing-Simmons wrote: It is better IMHO to have void peekstack(SV **stack,int items) and pass the values in. this is how I actually do it: void peekstack( register SV **sp, register SV **mark, I32 ax, I32 items ); called from XS as: peekstack(sp, mark, ax, items); I've found that without all the sp/mark/ax stuff the ST(n) macro doesn't work properly. Fine. I don't use the macro in my peekstack equivalent I just index stack e.g. SvPV(stack[i],...) BTW, this is transliterated from the Win32::GUI codebase. cheers, Aldo __END__ $_=q,just perl,,s, , another ,,s,$, hacker,,print; -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Retrieval of FILE* from a glob-ref under Win32
Tassilo Parseval [EMAIL PROTECTED] writes: Hi everyone, While trying to port one of my XS-modules to Win32 (not cygwin, but native Win32 using VisualC) the linker finally bombs out with an unresolved external symbol _PerlIO_exportFILE. As some #ifdef tests have shown, a number of macros (or perhaps all of them) as described under Co-existence with stdio in perlapio.pod are undefined. So how would I go about converting the macro #define sv_to_file(sv) (PerlIO_exportFILE(IoIFP(sv_2io(sv)), NULL)) to something Windows would understand? I would be using PerlIO_fileno() instead but as far as I know there's no way to gain a FILE pointer from a file-descriptor (or else correct me) and the library wrapped by this XS explicitely needs a FILE*. The whole thing is supposed to eventually work with ActiveState's Perl. If I recall correctly ActiveState perl is still perl5.6.? and so does not (really) have PerlIO - that is to say a PerlIO * _is_ a FILE *. However in such a system you are supposed to have PerlIO_exportFILE as a #define something like #define PerlIO_exportFILE(f,n) (f) You probably need to #define something else _before_ including perl.h and hence perlio.h and perlstdio.h to get FILE * visible. I don't have an perl5.6 source base to hand to check what that is but from memory it was something like: #define PERLIO_NOT_STDIO 0 #include perl.h Thanks for any insight, Tassilo -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Having a C function directly push onto the stack
: style xsub using XS-ish macros args go as ST(0)..ST(N). (So as you know you are going to return 1 or 9 values you don't _need_ to use PPCODE - but it is harmless.) PPCODE: is different it does a stack adust by number of args before the body gets invoked - so top of stack is now pointing at 1st arg so you can just XPUSH() return values. The other main thing you need to keep in mind is that EXTEND (or the implied one in XPUSHs) can re-allocate stack and so it may move wholesale in memory. I think the XS macro ST(n) dodges this issue by working in offsets from _the_ global variable which holds bottom-of-stack. But dSP / PUTBACK and PUSH are working with a cached local copy of top-of-stack pointer. I know the .h files are not as clear as we would like, but it is worth taking a look at them when you are unclear. I believe all this is covered in Simon's book ... Thanks in advance for any explanations, Tassilo -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Having a C function directly push onto the stack
Nicholas Clark [EMAIL PROTECTED] writes: On Fri, Jan 17, 2003 at 12:40:49PM +, Nick Ing-Simmons wrote: The other main thing you need to keep in mind is that EXTEND (or the implied one in XPUSHs) can re-allocate stack and so it may move wholesale in memory. I think the XS macro ST(n) dodges this issue by working in offsets from _the_ global variable which holds bottom-of-stack. But dSP / PUTBACK and PUSH are working with a cached local copy of top-of-stack pointer. In both 5.005_03 5.9 the two definitions look like this: #define PUSHs(s)(*++sp = (s)) #define XPUSHs(s) STMT_START { EXTEND(sp,1); (*++sp = (s)); } STMT_END and EXTEND is defined to update the cached local copy sp: #define EXTEND(p,n) STMT_START { if (PL_stack_max - p (n)) { \ sp = stack_grow(sp,p, (int) (n)); \ } } STMT_END so I think that there isn't actually a problem. But, obviously, I could be wrong, as XS isn't really something I know that much about. The problem I was alluding to needs the definition of 'sp' as well: pp.h:#define dSPregister SV **sp = PL_stack_sp Here 'PL_stack_sp' is _the_ global variable and 'sp' is a local copy So if you have a function: func(...) { dSP; /* Declares sp and inits from PL_stack_sp */ XPUSH(...) PUTBACK; /* copy sp to PL_stack_sp */ } And then have XS code call it CODE: ... func(); SPAGAIN; /* if you use sp anywhwere after this point */ ... XS_RETURN(n); /* Is immune as uses global PL_stack_base */ There are thus really two ways of working with the stack: A. dSP/XPUSH/EXTEND/PUTBACK/SPAGAIN originaly developed for perl ops B. items/ST(N)/XSRETURN(N) intended for XS CODE: blocks. They can be mixed but a little care is needed. Nicholas Clark -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: How to use fclose() with ActivePerl
Steve Hay [EMAIL PROTECTED] writes: Yes that is it. You need to use PerlSIO_fx() for Standard IO under PERL_IMPLICIT_SYS. Thanks for the reply. That fixed it straight away. Perhaps somebody could do a DOC PATCH for Perl about this if it hasn't already been done. My Perl 5.8.0 POD documents refer to lots of PerlIO_*() functions, but grep()ing the entire POD sources for PerlSIO_*() I see no mention of them at all. The whole PERL_IMPLICIT_SYS thing is really an ActiveState invention and PerlSIO_* should really be documented along with PerlLIO_*() PerlProc_*() and various others. I think I understand how they work, but in general for PERL_IMPLICIT_SYS HowTo questions it is probably best to ask ActiveState. Two more questions about this: 1) Am I right in thinking that these PerlSIO_*() functions do the right thing where PERL_IMPLICIT_SYS is not defined? (It appears to from repeating the build with my (non-ActivePerl) Perl.) Yes they do. 2) What's the best way to go about getting my XS to build under both Perl 5.8.0 and Perl 5.6.x as well? The PerlSIO_*() functions don't appear to be in those older versions. Is it simply by way of #if/#else statements making use of the #define's in patchlevel.h that specify the Perl revision/version/subversion? Perl5.8 introduced _real_ PerlIO *. The things that are now PerlSIO_() used to be PerlIO_() for PERL_IMPLICIT_SYS - but that got in the way of using stdio under PerlIO. Also, under Perl 5.6.1/PERL_IMPLICIT_SYS the compiler is happy about fclose(), but seems to have a problem with the PerlIO_importFILE() function: warning C4047: 'function' : 'int ' differs in levels of indirection from 'const char *' warning C4024: 'PerlIO_importFILE' : different types for formal and actual parameter 2 warning C4133: 'function' : incompatible types - from 'struct _PerlIO *' to 'struct _iobuf *' The first two warnings here seem to stem from the odd prototype that is given in the extern declaration in iperlsys.h under PERL_IMPLICIT_SYS: extern PerlIO *PerlIO_importFILE(FILE *,int); (I was expecting (FILE *, const char *) here, which is what it now is under Perl 5.8.0 [in perlio.h] -- was that just a bug in Perl 5.6.x?) The last warning looks similar to problem that I had with fclose() under Perl 5.8.0/PERL_IMPLICIT_SYS. The linker also bombs out with: error LNK2001: unresolved external symbol _PerlIO_importFILE Where is this extern PerlIO_importFILE() supposed to come from? Under perl5.6 a PerlIO * _is_ a FILE * so PerlIO_importFILE can be a no-op macro (I think this is still true under PERL_IMPLICIT_SYS). -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Namespace Issues
John Lenz [EMAIL PROTECTED] writes: Hi. We have been having a bunch of problems recently with SWIG (http://www.swig.org) and Perl 5.8.0. I am running Debian unstable, but we have also seen this problem on Solaris. I have reduced the problem to this short file #include EXTERN.h #include perl.h #include XSUB.h #include iostream int main() { return 42; } If you attempt to compile this file, a lot of errors having to do with do_open are generated. The problem is, iostream has a private function of a class named do_open. It took me a while to find because here is private member of a class that is inside a namespace conflicting with a define in the perl headers. Normally, you could just change the order of including the files, but for SWIG that is difficult/impossible because the C++ file is generated and any input file can tell SWIG to include iostream at any point in the file. This is possibly a SWIG problem in that it could do a better job here. I had not realized that: /* NO_EMBED is no longer supported. i.e. EMBED is always active. */ made it into the mainline - this is a step backwards :-( So my question is, how can I get rid of all the macros polluting the global namespace? Since this is a generated file, we can take care of the context stuff. Really I just want a way to not include embed.h in these files, and then use the perlapi though all the Perl_ and PL_ macros so that perl stays in its own namespace. The only thing I can suggest at present is to create a noembed.h and ask SWIG to include that before iostream. It would contain #undef do_open etc. John -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Enums
[EMAIL PROTECTED] writes: I have a header file with an enum, typedef enum { one two } OneTwo; ..in the xs I used #define one 0 #define two 1 char * char * ??? one() CODE: #ifdef one RETVAL = one; #else croak(Your vendor has not defined the macro one); #endif OUTPUT: RETVAL ...etc Is there a better way to handle enums? I tend to treat them as constant subs something like: /* Make function-like things for XS to call #define ENUM_one() one #define ENUM_two() two MODULE PREFIX ENUM_ PROTOTYPES : ENABLE IV ENUM_one() IV ENUM_two() Here ENUM_ -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Replacing values in two hashes
Roman Porizka [EMAIL PROTECTED] writes: Hello, I'm trying to exchange values in two hashes. These values are lists of hashes. I tryied to use combination of hv_fetch and hv_store, but it didn't work: SV ** temp_loop1; SV ** temp_loop2; temp_loop1 = hv_fetch(temp_include,some_key,strlen(some_key),0); temp_loop2 = hv_fetch(param_map[0],some_key,strlen(some_key),0); hv_store(param_map[0],some_key,strlen(some_key),*(temp_loop1),0); After this, there are the same values in temp_loop1 and temp_loop2. You only show 1 store - did you really mean exchange? As you might guess from the return type of SV ** fetch returns a pointer to location where SV * is stored. So if you change the value in hash you fetched from the SV ** stays the same (for a particular key, and assuming there is no tie or magic involved) but the SV * stored there changes. So you need to save the SV * : temp_loop1 = hv_fetch(temp_include,some_key,strlen(some_key),0); temp_loop2 = hv_fetch(param_map[0],some_key,strlen(some_key),0); SV *temp_val = *temp_loop1; SV *param_val = *temp_loop2; hv_store(param_map[0],some_key,strlen(some_key),temp_val,0); hv_store(temp_include[0],some_key,strlen(some_key),param_val,0); If there _is_ tie or magic involved then you are probably better off making copies: SV *temp_val = newSVsv(*temp_loop1); hv_store(param_map[0],some_key,strlen(some_key),temp_val,0); Thanks for any informations Roman Porizka -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: HV to C struct
Tamar Shinar [EMAIL PROTECTED] writes: Hi, I am trying to write an xs interface to an external library. My code takes two perl arrays, allocates and populates corresponding C structures, and passes them to the library routine. The problem is that the program is unstable. It will sometimes cause core dumps in the external library. The library in itself is believed to be stable, so it seems to be something in the perl/C interface. I use the following three functions to retrieve values from my perl objects in order to copy them into the C structures. Does anyone see anything wrong here? thank you, Tamar ___ char * getString(HV * source, char * fieldName) { SV ** sv = hv_fetch(source, fieldName, strlen(fieldName), FALSE); if(!SvOK(*sv)) { printf(Error - hv_fetch %s returned bad sv\n, fieldName); } return SvPV(*sv, PL_na); } The 1st thing to notice is that return from hv_fetch can be NULL if field does not exist in the hash. So SvOK(*sv) will core dump, also you go on to de-ref the thing even if your test said SV was not okay. So you want something like this - you can provide safe values for not-there and undef cases - I have used NULL and as examples. SV **svp = hv_fetch(...) if (*svp) { if (SvOK(*svp)) { /* defined value of some kind (but may not be a string, but SvPV will force that for us). In perl5.6+ you may need to consider case of string being in UTF-8 */ return SvPV_nolen(*svp); } else { /* undef value */ return ; } } else { /* No such member */ return NULL; } -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Returning Boolean
Steve Hay [EMAIL PROTECTED] writes: Just a quick question: Is there a preferred way to return a Boolean value from an XSUB? Return sv_yes or sv_no - that is what they are for ... I could have an SV* function returning PL_sv_yes/PL_sv_no (or PL_sv_undef?), or a bool function returning TRUE/FALSE, or even just an int function returning 1/0. Is there any advantage in any of these? Depends what the consumer of returned value is going to use it for. But normal perl code is going to return sv_yes/sv_no so to make XSUB just like that use those. In quasi-numeric contexts 1/0 (aka TRUE/FALSE) returned as SvIV may make more sense. Steve -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Delaying a destroy on a parent object
Bill Moseley [EMAIL PROTECTED] writes: I have some code that works like: my $result_object = $search_object-query($query); I'd like to prevent $search_object from being destroyed until $results_object is gone. Normally I could do $results_object-{parent} = $search_object; But in this case $results_object is a pointer to a C struct not a hash (or an array). Are there any options other than returning a blessed array or hash ref as my object? All you really want to do is increment the SvREFCNT of the parent object for the duration. You can do that my hand and then (if you cannot already locate it) save pointer to search object's SV in the C struct. Does that help ? Thanks, Here's the real code: $results = $swish-SwishQuery($query); so the current xs code is: SW_RESULTS SwishQuery( swish_handle, query = NULL ) SW_HANDLE swish_handle char *query PREINIT: char * CLASS = SWISH::API::Results; Where SW_RESULTS is a O_OBJECT typemap. O_OBJECT sv_setref_pv( $arg, CLASS, (void*)$var ); -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Unicode and XS
Brian De Pradine [EMAIL PROTECTED] writes: Hello, I am writing a module using XS that will need to run on a number of different platforms, including mainframe. The problem that I have is that Perl on EBCDIC platforms uses UTF-EBCDIC internally, instead of UTF-8. This means that functions such as SvPVutf8(), if I understand the documentation correctly, will produce UTF-EBCDIC on EBCDIC platforms. Is there anyway that I can convert this output back to UTF-8? I _think_ the short answer is no. This always bothered me when I was doing the UTF-EBCDIC stuff. The snag being that perl's 'utf8' encoding uses core's SvUTF8 scheme - which is just fine if it _IS_ UTF-8 What we need for Encode::* to have its _own_ UTF-8 and UTF-EBCDIC encode/decode independant of what core is using... Thanks Brian -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: sv_setpvn buffer size limit???
Zoltan Magyar [EMAIL PROTECTED] writes: Hi, I'm working on a binary encryption library for perl. The library receives a few parameters, does the encryption and returns the encrypted data. Before the encryption takes place the required buffer size for the encrypted data is calculated (calling EncryptData with NULL output pointer). When this value (nOutDataLen) is calculated sv_setpvn is used to allocate the buffer for the result. This call seems to be failing somehow. The context is unsigned int EncryptData(pRemoteKey,pLightData,nLightDataLen,pHeavyData,nHeavyDataLen) char*pRemoteKey unsigned char* pLightData intnLightDataLen unsigned char* pHeavyData intnHeavyDataLen PPCODE: unsigned int nOutDataLen = 0; SV*svOutData = newSVsv(sv_undef); unsigned char* pOutData = NULL; unsigned int bRet = 0; /* make an initial call with a NULL buffer to get the output length */ bRet = EncryptData(pRemoteKey, pLightData, nLightDataLen, pHeavyData, nHeavyDataLen, NULL, nOutDataLen); /* calling with a NULL output buffer should always fail */ if(bRet == 0) { /* set up our output buffer */ sv_setpvn(svOutData, , nOutDataLen); That is going to try and copy nOutDataLen bytes starting at wherever C compiler has allocated the constant string. I think you want: /* make it a string - calling sv_upgrade() would be slightly more efficent */ sv_setpvn(svOutData, , 0); /* Grow buffer and get the pointer to the buffer */ pOutData = (unsigned char*) SvGROW(svOutData, nOutDataLen+1); /* tell perl number of valid bytes */ SvCUR_set(svOutData, nOutDataLen); /* now try and create the blob */ bRet = EncryptData(pRemoteKey, pLightData, nLightDataLen, pHeavyData, nHeavyDataLen, pOutData, nOutDataLen); } /* push the return values onto the stack */ . .. ... etc An alternative might be to allocate SV with a buffer: svOutData = newSV(nOutDataLen); SvCUR_set(svOutData, nOutDataLen); This code worked fine so far but it turned out recently that if the calculated result length is too long the code is failing. I did some sanity check and found that if nOutDataLen = 7361 then the library crashes but working fine if nOutDatalength = 7360. According to the debug session sv_setpvn is failing. Weird size is just distance from to end of allocated virtual memory segment. Interestingly the code is working fine when the compiler optimisations (used /O1) are turned off. Which probably allocates more strings or something making the fail point further away. I have used Win32 for the investigation and debugging but the library has similar problems on Linux (I'm not sure the problem is exactly the same on Linux as I haven't debugged it, but the symptoms are the same). I did quite long search on the net about this issue but I haven't found any similar (but found this list :-). Any thoughts? TIA Zoltan Magyar -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Embedding on Linux/390 -- Segfaults.
Greg [EMAIL PROTECTED] writes: I have a slightly modified version of the example in perlembed. compiling with gcc works on both Linux/Intel and Linux/390. compiling with g++ works on Linux/Intel but segfaults on Linux/390. the code: #define PERL_NO_GET_CONTEXT #include EXTERN.h /* from the Perl distribution */ #include perl.h /* from the Perl distribution */ #include stdio.h static PerlInterpreter *my_perl; /***The Perl interpreter***/ int main(int argc, char **argv, char **env) { my_perl = perl_alloc(); perl_construct(my_perl); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(my_perl, NULL, argc, argv, (char **)NULL); perl_run(my_perl); if (SvTRUE(ERRSV)) { printf(SvTRUE(ERRSV) is true\n); } else { printf(SvTRUE(ERRSV) is false\n); } perl_destruct(my_perl); perl_free(my_perl); } the behaviour on linux/390 when compiled with g++: $./interp -e'print Hello World\n;' Hello World Segmentation fault $ The seg fault is on the if (SvTRUE(ERRSV)) { line. Can anyone see what I'm doing wrong / whats happening? If it works in C, but fails on C++ then chances are the problem is not in the code but in the compile/link flags and libraries. (There is an outside chance that we are missing an extern C or some cast abstraction, but if it works with same compiler (g++) somewhere then that is unlikely.) Can you show those build command lines for linux/390 for C and C++? Does g++ build report any warnings? -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Embedding on Linux/390 -- Segfaults. (environment)
Greg [EMAIL PROTECTED] writes: ...and the environment is: Thanks - that in principle answers my how did you build the C version question. But I would still like to see commands you used to build the emedded version - particularly the g++ ones. The -V below shows a pile -f -DX and -l options which need to be applied to the g++ build and _where_ on command line(s) those ended up could explain something. $perl -V Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration: Platform: osname=linux, osvers=2.4.7-timer-smp, archname=s390-linux-thread-multi uname='linux winlnx8a 2.4.7-timer-smp #1 smp tue may 21 12:58:16 gmt 2002 s390 unknown ' config_args='-Doptimize=-g -Dcc=gcc -Dusethreads -Duseshrplib -des' hint=previous, useposix=true, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -I/usr/local/include -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' ccversion='', gccversion='2.95.3 20010315 (SuSE)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -ldl -lm -lpthread -lc -lcrypt -lutil perllibs=-lnsl -ldl -lm -lpthread -lc -lcrypt -lutil libc=, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.2.4' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic -Wl,-rpath,/usr/local/lib/perl5/5.8.0/s390-linux-thread-multi/CORE' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY USE_ITHREADS USE_LARGE_FILES PERL_IMPLICIT_CONTEXT Built under linux Compiled at Jun 6 2003 11:35:53 @INC: /usr/local/lib/perl5/5.8.0/s390-linux-thread-multi /usr/local/lib/perl5/5.8.0 /usr/local/lib/perl5/site_perl/5.8.0/s390-linux-thread-multi /usr/local/lib/perl5/site_perl/5.8.0 /usr/local/lib/perl5/site_perl . $ -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Embedding problems with DynaLoader on Solaris
) $(PTCLIBS_DLL) $(LD) $(LDFLAGS) -o $(EXE_DLL) $(OBJS) $(PTCLIBS_DLL) $(PERL_LIBS) $(SYSLIBS) # object dependencies properl.o: properl.c $(CC) $(CFLAGS) properl.c dll: $(EXE_DLL) Marc -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: getenv() problems
[EMAIL PROTECTED] writes: ..The problem is that the c function is not getting the vars from the env, when running under Perl. The getenv() does not seem to work. If I set the variables $ENV{PROJECT} = and $ENV{SERVICE} = 1, call the function OpenLog(Arg, Arg, , ), the function will see the 2 empty strings and attemt to read the values from the env. These env variables could be set by a shell script before the perl is run. The perl code could be last in a series of utilities that use these env vars. It works if the actual arguments are sent to the function, but I would like to have the interface behave as the C calls do. Here is some of the C code if my explaination is to vague, DotsLog.Project = GETENV(inproject, PROJECTNUM); #define GETENV(var, env) ( (var) == NULL ? getenv((env)) : (var) ) But you are not passing NULL you are passing NULL is (char *) 0 is pointer to a byte containing '\0'. You may need a custom typemap to cause (or better undef) to be passed to your library as NULL. -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Embedding problems with DynaLoader on Solaris
Marc Mettes [EMAIL PROTECTED] writes: Nick Ing-Simmons wrote: The compile and link lines look like this: gcc -c -fPIC -DPRO_MACHINE=19 -DPRO_OS=3 -DSOLARIS -I. -Iincludes -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/perl/lib/5.6.1/sun4-solaris/CORE properl.c ld -G -Bsymbolic -o properl.dll properl.o ./protk_dll.a /usr/perl/lib/5.6.1/sun4-solaris/auto/DynaLoader/DynaLoader.a -L/usr/perl/lib/5.6.1/sun4-solaris/CORE -lperl -L/opt/gcc-2.95.3/lib/gcc-lib/sparc-sun-solaris2.6/2.95.3 -lgcc -lsocket -lnsl -lw -lm -ldl -lc Can you try without the -Bsymbolic ? Without -Bsymbolic, the app cannot be loaded at runtime. It is an option used by example makefiles with this CAD api, and it seems that I cannot remove it. But you can turn it off for some libraries. Without a Solaris machine to test it on I cannot be sure but I am reasonably certain that -Bsymbolic binding of -ldl renders it useless (the same may be true of -lnsl IIRC). Try re-enabling dynamic binding for -ldl and -lc ld -G -Bsymbolic -o properl.dll properl.o ./protk_dll.a /usr/perl/lib/5.6.1/sun4-solaris/auto/DynaLoader/DynaLoader.a -L/usr/perl/lib/5.6.1/sun4-solaris/CORE -lperl -L/opt/gcc-2.95.3/lib/gcc-lib/sparc-sun-solaris2.6/2.95.3 -lgcc -lsocket -lnsl -lw -lm -Bdynamic -ldl -lc Or perhaps just the problem library: ld -G -Bsymbolic -o properl.dll properl.o ./protk_dll.a -Bdynamic /usr/perl/lib/5.6.1/sun4-solaris/auto/DynaLoader/DynaLoader.a -L/usr/perl/lib/5.6.1/sun4-solaris/CORE -lperl -L/opt/gcc-2.95.3/lib/gcc-lib/sparc-sun-solaris2.6/2.95.3 -lgcc -lsocket -lnsl -lw -lm -ldl -lc -B symbolic In dynamic mode only. When building a shared object, binds references to global symbols to their defini- tions, if available, within the object. Normally, references to global symbols within shared objects are not bound until runtime, even if definitions are available, so that definitions of the same symbol in an executable or other shared object can override the object's own definition. ld will issue warnings for undefined symbols unless -z defs overrides. That would also imply that code is going to define symbols which conflict with root executable. This is going to be a problem because the way perl dynamic loading works relies on symbols from -lperl being available to loaded perl extensions. We have not got that far yet, but when you do you are going to have to use one of the dlopen() tricks discussed on this list recently, to make perl's symbols available and that will make these must-be-symbolic symbols visible too. I am using gcc built on Solaris 2.6, but linking and running the app on Solaris 8. Could that be causing some issues? I think gcc-2.8+ is much better at this that earlier ones but it could be causing problems. Marc -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Question about embedding interfacing with C++ objects
Brett W. McCoy [EMAIL PROTECTED] writes: I am building an embedded Perl scripting environment for a 3D modelling package. I have the basic scripting engine working (that was the easy part), but now my challenge is to be able to directly interface with C++ objects inside the application. What I really want to do is to be able to build Perl objects on the fly from live C++ objects. Which can be done if you have a clear policy for how a C++ object becomes a perl object. The snag is that C++ is compile time typed so each C++ class needs a method to convert itself to/from perl objects. I have some day-job related code (which I have yet to shake loose into something I can distribute) which uses g++ -E and then a parse of result to create perl bindings to all the public methods of a class heirachy. (i.e. you use it instead of xsubpp and it produces Class.cpp). At bottom of this are the utility functions: void * SV_to_object(pTHX_ SV *sv, const char *classname) { if (SvOK(sv)) { if (sv_derived_from(sv,classname) SvIOK(SvRV(sv))) { IV tmp = SvIV(SvRV(sv)); return (void *) INT2PTR(void *,tmp); } croak(Not a %s (%_),classname,sv); } return 0; } void object_to_SV(pTHX_ SV **svp, const char *classname, IV value) { if (value) { SV *sv = sv_newmortal(); sv_setref_iv(sv,classname,value); *svp = sv; } else { *svp = PL_sv_undef; } } void enum_to_SV(pTHX_ SV **svp, const char *classname, IV value, const char *str = 0) { SV *sv = sv_newmortal(); *svp = sv; sv_setref_iv(sv,classname,value); if (str) { sv_upgrade((sv = SvRV(sv)),SVt_PVIV); sv_setpv(sv,str); SvIOK_on(sv); } } IV SV_to_enum(pTHX_ SV *sv, const char *classname) { if (sv_derived_from(sv,classname) SvIOK(SvRV(sv))) { return SvIV(SvRV(sv)); } croak(Not a %s (%_),classname,sv); return 0; } The perl script (which I call findclass) then arranges to pass right thing to classname args of those. The perl classnames are same as the C++ ones. The fun part is handling overloaded functions - i.e. figuring out from the number and type of args passed which C++ method to call and producing XS code that calls method with correctly converted args to call that method. For instance, the user has the application running with an open document with a hierarchy of objects, and each level (application, document, object) has a certain scripting context associated with it (not too different from DOM, I think), so you can run, say, a script that modifies the behavior of a group of objects as they are being animated. I found, on CPAN, an aborted attempt at creating a C++ interface to the Perl API, and that might be a good starting point, but I wanted to see if anyone else has ventured into this arena. You can embed perl in C++ using perl's C API. You just have to to C-ish housekeeping rather than C++-ish housekeeping. -- Nick Ing-Simmons http://www.ni-s.u-net.com/
Re: Error:initializer element is not constant.
Sisyphus [EMAIL PROTECTED] writes: My guess is that 'mpz_add' has been #defined to something like (*FunctionTablePtr-MPXADD) which is a common trick with dynamicaly loaded code. Try just preprocessing the file (dmake GMP.i might work for this??) D:\gmp-4.1\demos\perldmake gmp.i dmake.exe: Error -- Don't know how to make `gmp.i' Is that what you meant ? Yes that is what I meant. So you have to do it the hard way: del GMP.o dmake -n GMP.o Note the command would be used to compile that it prints with all the -I flags etc etc. then add a -E and change -o GMP.o to -o GMP.i Then look and see what happens after pre-processing. Yes, I posted to the GMP list as well, and received similar advice. To quote - Hmm, yep, DLL imported functions don't work in initializers (with gcc). Another option mentioned was to try with a statically-built GMP. So, with a fresh slate, I ran 'perl makefile.pl' and edited the generated makefile to specify 'CC = g++'. That had the desired effect of invoking g++ instead of gcc, but unfortunately led to parse errors: GMP.xs:294: parse error before `{' GMP.xs: In function `void class_or_croak(...)': GMP.xs:295: parse error before `,' GMP.xs:296: parse error before `;' dmake.exe: Error code 1, while making 'GMP.o' where the relevant code (starting at line 292) is: static void class_or_croak (SV *sv, classconst char *class) { if (! sv_derived_from (sv, class)) croak(not type %s, class); } Well know gotcha that - 'class' is a keyword in C++ I usually do something like: perl -pi.old -e s/\bclass\b/Class/g GMP.xs I might just use the msvc-built binaries in my gcc-built perl. My reluctance in doing so is that my msvc compiler is non-optimising. Given that GMP dll *was* built with an optimising compiler, it may well be insignificant whether or not the actual perl module gets built with an *optimising* compiler. (Anyone have any thoughts on that aspect ?) One further question: Since gcc, or g++, as the case maybe, is compiling GMP.c (afaik), why is it that the errors are being reported in GMP.xs (not the file that's actually being compiled) ? xsubpp puts in #line directives to point you at the right place to change the file. I'm sure that I have, in building other modules, received errors pertaining to both xs and c files (mostly the xs file, but sometimes the c file) - but I'm just wondering what it is that determines whether the error is going to be reported as being in the xs file or the c file. There are parts of GMP.c which are verbatim stuff. At one time I tried to add more #line directives to poing at the boiler-plate code in xsubpp itself. Another place code can comefrom is the typemap file ...
Re: Test::More problem
Billy Patton [EMAIL PROTECTED] writes: something strange happening with testing using Test::More I have a t directory with my .t files Not even sure how to ask about problem? So forgive if problem is sketchy. If you don't use Test::More you will probably not be able to help. I can run perl -Mblib t/NodeMalloc.t and everything is fine when I run make test and it runs PERL_DL_NONLAZY=1 /data/cdmg/perl/5.8.0-32/SunOS/bin/perl -MExtUtils::Command::MM -e test_harness(0, 'blib/lib', 'blib/arch') t/*.t That is usually because you have written something to stdout which isn't a result report. Stdout should have nothing but things that match one of these 1\.\.\d+$ #.*$ (not )ok \d+$ And the ok numbers must be in strictly increasing order. That said your tests are using @_ and %_ is stange ways would it not be better to use norma vars like @array and %hash rather than magical perl system variables? @_ in particular is going to change under you... (I don't think %_ means anything but is living a magical *_ glob ...) I get: t/NodeLayer...ok t/NodeMalloc..ok 92/94Confused test output: test 92 answered after test 92 t/NodeMalloc..ok 93/94Confused test output: test 93 answered after test 93 t/NodeMalloc..FAILED test 91 Failed 1/94 tests, 98.94% okay Would seem to be that I have a missing '/ somewhere. I use gvim and it is color syntax'd I see no problems. Here is snippett of xs code: case lCLF: if (items NE 5) { lERROR(Node::New : CLF needs layer, width and pointer to list of points.); goto END; } if (SvTYPE(ST(2)) NE SVt_IV) { lERROR(Node::New : CLF : Arg 2 must be layer integer!); goto END; } if (SvTYPE(ST(3)) NE SVt_IV) { lERROR(Node::New : CLF : Arg 3 must be width integer!); goto END; } if (SvTYPE(ST(4)) NE SVt_RV) { lERROR(Node::New : CLF :arg 4 must be a reference!); goto END; } if (SvTYPE(SvRV(ST(4))) NE SVt_PVAV) { lERROR(Node::New : CLF :arg 4 must be reference to an array!); goto END; } av= (AV*) SvRV(ST(4)); npts = av_len(av) / 2; for (i = 0,npts = 0; i av_len(av); i++,npts++) { pts[npts].x = SvIV(*av_fetch(av,i,0)); i++; pts[npts].y = SvIV(*av_fetch(av,i,0)); } retp = NodeMalloc(ltype ,SvIV(ST(2)) ,SvIV(ST(3)) ,npts,pts); break; Here is my .t: comments below use Data::Dumper; use Test::More tests = 94 ; use Laff; # failure ok(0); # successful ok(1); # a list to be used multiple times @pts = qw ( 0 0 0 10 10 10 10 0 0 0); ## ## build main tag types ## ok($np = Laff::Node-New, 'malloc empty node'); ok($np-Type == lNOOP , 'confirm type is lNOOP'); ok(! Laff::Node-New(1) , 'fails does know type 1'); ok($np = Laff::Node-New(lBOUNDARY) , 'create BOUNDARY node'); ok($np-Type == lBOUNDARY , 'confirm node is BOUNDARY'); ok($np = Laff::Node-New(lDETAIL) , 'create lDETAIL node'); ok($np-Type == lDETAIL , 'confirm node is lDETAIL'); ok($np = Laff::Node-New(lDIAGNOSTIC) , 'create lDIAGNOSTIC node'); ok($np-Type == lDIAGNOSTIC , 'confirm node is lDIAGNOSTIC'); ok($np = Laff::Node-New(lNAMES), 'create lNAMES node'); ok($np-Type == lNAMES , 'confirm node is lNAMES'); ok($np = Laff::Node-New(lPORTS), 'create lPORTS node'); ok($np-Type == lPORTS , 'confirm node is lPORTS'); ok($np = Laff::Node-New(lSTRUCT) , 'create lSTRUCT node'); ok($np-Type == lSTRUCT , 'confirm node is lSTRUCT'); ok($np = Laff::Node-New(lSYMBOLIC) , 'create lSYMBOLIC node'); ok($np-Type == lSYMBOLIC , 'confirm node is lSYMBOLIC'); ### ## ## build and check arb ## ### ok(! Laff::Node-New(lARB) , 'fail no layer or reference to list'); ok(! Laff::Node-New(lARB,fail) , 'fail arg 2 must be a int'); ok(! Laff::Node-New(lARB,111,fail) , 'fail arg 3 will not accept string'); ok(! Laff::Node-New(lARB,111,111) , 'fail arg 3 will not accept int'); ok(!
Re: Where is PerlIO_isutf8()?
Steve Hay [EMAIL PROTECTED] writes: Nick Ing-Simmons wrote: Most of the PerlIO_Xxxx() are handled as a group in makedef.pl Which group -- the group in @layer_syms, or the group in __DATA__? layer_syms is the one I meant. __DATA__ is a hacking region I wish I had never invented. (My defence your honour was that only editor I had at the time was NT4.0's notepad and wholesale changes scared me.) i.e. is my possible PATCH (http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-07/msg01096.html) correct or not? (Vadim Konovalov believes it is correct -- http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-07/msg01101.html). If it is correct then will it be applied in time for perl-5.8.1 as Nicholas Clark suggested? Steve
Re: Warnings from perlvars.h
[EMAIL PROTECTED] writes: On Thu, Aug 07, 2003 at 04:32:22PM +0100, Nick Ing-Simmons wrote: bash-2.03$ ldd blib/arch/auto/Text/Aspell/Aspell.so libaspell.so.15 = /home/users/w/wh/whmoseley/aspell/lib/libaspell.so.15 libucb.so.1 = (file not found) [...] Fine! I'll add -L/usr/ucblib -lucb to my LIBS. Be VERY wary of using anything usb-ish on Solaris. Solaris is SVR4 variant and UCB compatibility headers and libraries are/were very poor. Hum, probably a basic question, but how do I find out what's brining that library in? Using ldd - my guess is that it is /home/users/w/wh/whmoseley/aspell/lib/libaspell.so.15 try running ldd on that ... I'm not specifically requesting it (I'm adding it to LIBS because it gets added to the runtime lib requirements but is not found in normal library search paths. Thanks,
Re: I need your help
Jane Li [EMAIL PROTECTED] writes: Dear Ms./Sir, I am working on the problem of calling C++ functions from Perl. Your clear tutorial style web page: Gluing C++ And Perl Together gave me really great help. But what I am sticking now is that I have to embed a C++ function which asks two input parameters of string class data type like this: void func(string c1, string c2, classA* c3); The typemap file are like this: TYPEMAP THES * O_OBJECT string O_OBJECT That is not appropriate typemap for std::string Now that STL is geting standard perhaps we should add something to the default map. Both perl strings and std::string can handle lengths so the converters are straight forward: TYPEMAP string T_STDSTRING INPUT T_STDSTRING (void) SvPV_nolen($arg); $var(SvPV_nolen($arg),SvCUR($arg)) OUTPUT T_STDSTRING sv_setpvn($arg, $var.c_str(), $var.length()); Above is un-tested. Another approach might be to define typeconverters between string/SV * and then just have XS code use an SV as a string TYPEMAP string T_SV And then have these at the top of your .xs file (after #including perl.h) inline operator SV *(const string var) { // This creates a new SV every time - beware memory leaks return newSVpvn(var.c_str(), var.length()); } inline operator string (SV *const arg) { STRLEN len; const char *s = SvPV(arg,len); return string(s,len); } However, when I use make test to run the program, it reports bunches of lines like this: make test g++ -c -fno-strict-aliasing -I/usr/local/include -O2 -march=i386 -mcpu=i686 -DVERSION=\0.01\ -DXS_VERSION=\0.01\ -fPIC -I/usr/lib/perl5/5.6.1/i386-linux/CORE thesaurusLib.c thesaurusLib.c: In function `void XS_thesaurusLib_relatedness (CV *)': thesaurusLib.c:80: no matching function for call to `basic_stringchar, string_char_traitschar, __default_alloc_templatetrue, 0 ::basic_string (IV)' /usr/include/g++-3/std/bastring.h:176: candidates are: basic_stringcharT, traits, Allocator::basic_string () [with charT = char, traits = string_char_traitschar, Allocator = __default_alloc_templatetrue, 0] /usr/include/g++-3/std/bastring.h:177: basic_stringcharT, traits, Allocator::basic_string (const basic_stringcharT, traits, Allocator ) [with charT = char, traits = string_char_traitschar, Allocator = __default_alloc_templatetrue, 0] make: *** [thesaurusLib.o] Error 1 at the top of .xs file I have already included the header file like this: #include string The other parts are made by following the steps in your webpage. It seems that xsubpp cannot recognize the string class in C++, is it right? Or are there any ideas about this? This problem has puzzled me for days and I have to deal with it in order to continue my work. I really need your help or any ideas. Thanks in advance. Regards, Jane.
Re: Safefree() an array of arrays
Sisyphus [EMAIL PROTECTED] writes: Hi, I'm building an n x n 2D array. I've declared the structure: int ** aoa; I've allocated the memory: Newz(100, aoa, n, int); Observation you asked for n 'int's there but you are stuffing it with n 'int *'s That should have been Newz(100, aoa, n, int *); if(aoa == NULL) croak(Failed to allocate rows); for(i = 0; i n; ++i) { Newz(i, aoa[i], n, int); if(aoa[i] == NULL) croak(Failed to allocate columns); } I've successfully placed (and accessed) data in the structure, so I guess I've done it correctly so far. To free the memory I've done: for(i = 0; i n; ++i) Safefree(aoa[i]); But there's still some more memory to Safefree() isn't there ? I tried adding: Safefree(aoa); But that crashes the program. It shouldn't What do I need to do ? You did it correctly as far as I can see, my guess is that you have corrupted memory around aoa. Also, as regards the first argument supplied to New() - is there any reason that it should be different (ie unique) for each 'New()' call within a program ? It is not normally used - it is legacy of really old allocation checker. The number is a tag which describes why that chunk was allocated in some vague way. I'm working on Win2k, perl5.6.1, and writing code to be used with Inline C if any of that makes any difference. (I don't think it does :-) AFAIK int and int * are same size there, so I am at a loss as to what is wrong. On linux you could use valgrind to check this stuff... Cheers, Rob
Re: ExtUtils::MakeMaker problem
Billy N. Patton [EMAIL PROTECTED] writes: I looked through man pages and read about overloading colon definitions. I'm already doing that. But MakeMaker spits out : FIXIN = $(PERLRUN) -MExtUtils::MY \ -e MY-fixin(shift) So you want to over-ride PERLRUN so that it uses the perl you want to apear in #! line rather than the one with the links resolved. The easy way to do that it modify Config.pm to have right path-to-perl (or get your admin to do that right in the 1st place.) But assuming you need to do this in Makefile.PL you need something like: package MY; sub constants { local $_ = shift-SUPER::constants(@_); s#/apps/perl/5.8.0/bin/perl#/usr/local/bin/perl#g; return $_; } But you probably want to generalize the from part of subsitute. I tried : sub MY::subdirs { ' FIXIN = all :: But that resulted in : EXE_FILES = clean_laff FIXIN = $(PERLRUN) -MExtUtils::MY \ -e MY-fixin(shift) pure_all :: $(INST_SCRIPT)/clean_laff @$(NOOP) realclean :: rm -f $(INST_SCRIPT)/clean_laff $(INST_SCRIPT)/clean_laff: clean_laff Makefile $(INST_SCRIPT)/.exists @rm -f $(INST_SCRIPT)/clean_laff cp clean_laff $(INST_SCRIPT)/clean_laff $(FIXIN) $(INST_SCRIPT)/clean_laff [EMAIL PROTECTED](CHMOD) $(PERM_RWX) $(INST_SCRIPT)/clean_laff # --- MakeMaker subdirs section: FIXIN = Which tried to execute clean_laff. I dont want to overload : $(INST_SCRIPT)/clean_laff: That would result in mas quantities of overloaded colon definitions. If I have to do that then I don't need to CORNfusion of MakeMaker Steven N. Hirsch wrote: On Tue, 19 Aug 2003, Billy N. Patton wrote: I use a ExtUtils::MakeMaker to create my makefile. In my source file I have: #!/usr/local/bin/perl use strict; require 5.005; After installation into the blib and therefore the final destination I get: #!/apps/perl/5.8.0/bin/perl eval 'exec /apps/perl/5.8.0/bin/perl -S $0 ${1+$@}' if 0; # not running under some shell use strict; require 5.005; ls -l /usr/local/bin/per* /usr/local/bin/perl - perl-5.8.0 /usr/local/bin/perl-5.8.0 - /apps/perl/5.8.0/bin/perl I have determined that the following line makes the change: /usr/local/bin/perl -MExtUtils::MY -e MY-fixin(shift) blib/script/clean_laff How do I stop this from happening? Although there may be a simpler method, I usually resort to subclassing the offending method. There's some verbiage in the MakeMaker man page which gives an example of the technique. If anyone knows of comprehensive documentation on MakeMaker (past what's in the man pages) please speak up? Steve
Re: Perl stacks and caller function
Christian Jaeger [EMAIL PROTECTED] writes: Hello (I've just subscribed to this list) I've tried to understand pp_caller, So have I ;-) and copied most code from it into an own function (I don't like the overhead of setting up the perl stack and call into a perl function just to find out who was the last caller..), but it doesn't work as expected. I seems like the way pp_caller walks the stack is in the reverse order of how perl's caller() function works (i.e. caller(0) is the last index my code is going to finds, and the first package my code finds is about the last one caller() will return in while (defined($pack=caller($n))){$n++}), and apart from being a bit weird I don't know how to find out hen I'm at the end of the stack. I don't yet understand how the stack (or stacks, man perlhack tells me about the different stacks, but I don't know where they all are located in the C code) works, i.e. the curstackinfo with its next/prev pointers vs. its cxstack member which seems to be a C array (where I don't know how long it is). (I also don't understand what dopoptosub_at does.) You are probably going to have to figure those things out, we will try and help if we can... If you do please consider submitting a doc patch that describes what you discover. PS. the best thing to recognize the caller package would be a pointer that doesn't change, so I don't need to verify the whole package name but only compare the pointer. Is cop_stash from struct cop (as returned by pp_caller) such a reliable pointer? That at least is easy. Yes cop_stash is what you want. A package is a name space, that namespace is a hash (i.e. an HV *) i.e. %main::Package:: Note the trailing :: These hashes are called 'stashes'. So comparing stash is fine. PS.2: am I correct assuming that calling an xs function changes the current namespace to the namespace as defined in the .xs file? No. That is one of things that does not happen when calling an XSUB. But saddly this was not fool-proof. package Foo; somexsub(anotherfunc()); When in somexsub() then current package was _probably_ Foo. But if anotherfunc() (which was called to create your args) is a function-in-perl and has been imported - then I _think_ the current package _used_ be left pointing there. This may have been fixed by now. A side-effect of the no above is of another XSUB calls yours (via call_sv() say) then the calling package is not clearly defined - do you want the package of the current statement or the one that provided the calling XSUB? The other thing to stir into the mix is the effect of eval {} which complicates the stack stuff... Is there any way to easily get at the current namespace (i.e. the __PACKAGE__ value) from xs? If the current namespace is not changed then this value would already be what I'm looking for.. PL_curcop is a pointer to the current context-op. So you _may_ be able to get away with PL_curcop-cop_stash but you need to try it under various strange cases and check you always get what you expect.
Re: Perl stacks and caller function
Christian Jaeger [EMAIL PROTECTED] writes: At 10:56 Uhr +0100 21.08.2003, Nick Ing-Simmons wrote: These hashes are called 'stashes'. So comparing stash is fine. Sorry, I copy-pasted the wrong entry, I've meant cop_stashpv. pp_caller returns CopSTASHPV(), and this macro accesses cop_stashpv if USE_ITHREADS is true, and HvNAME(CopSTASH(x)) otherwise. In the name of portability I probably have to be content with the resulting char*. Now I'm wondering if this one is stable as well. Maybe. It may not be constant across threads, I can't remember which things are shared and which are duplicated when you clone a new thread. A side-effect of the no above is of another XSUB calls yours (via call_sv() say) then the calling package is not clearly defined - do you want the package of the current statement or the one that provided the calling XSUB? I'm not sure what you mean with the [statement] that provided the calling XSUB. Suppose in some .xs file I have MODULE = Bar PACKAGE = Bar DoCall(SV *hvref) CODE: { SV **svp = hv_fetch((HV *)SvRV(hvref),d,1,0); // will call your FETCH } And then over in perl: package Foo; Bar::DoCall(\%oneofYourHahes); Should you be checking Bar (the notional package name of XSUB accessing the hash) or Foo (the current package)? Class::PredefinedFields::Tie::{FETCH,STORE,..} must know that $obj-{d}=1 is in package main. (And Class::PredefinedFields::import must know that use Class::PredefinedFields is in package Foo, but I'm not yet sure I'll implement the import function in XS.) The other thing to stir into the mix is the effect of eval {} which complicates the stack stuff... I've noticed the several cx_type's. But it shouldn't matter since I simply want the *last* statement that's calling me. If you get into stack tracing though the eval {} still gets you eval { $obj-{d} = 1 }; You _immediate_ caller is the eval. An presumably user put it there so he can catch your croak-s ... PL_curcop is a pointer to the current context-op. So you _may_ be able to get away with PL_curcop-cop_stash but you need to try it under various strange cases and check you always get what you expect. Coool, works (on 5.6.1)! Even simpler than I expected :) (Well since cop_stash does not exist when compiling with ithreads, maybe I should use CopSTASHPV(PL_curcop).) Likely. I'll see if it will be enough in all cases. Thanks, Christian.
Re: Resolve symbols
Bustamam Harun [EMAIL PROTECTED] writes: Hmm. I only see this in your reply. Is there anything else that was missing? Nick Ing-Simmons wrote: No Message Collected Odd it made to to the list for me here is what I said: Nick Ing-Simmons [EMAIL PROTECTED] writes: Bustamam Harun [EMAIL PROTECTED] writes: Is there anyway I could override how Perl resolve symbols, like for instance: use mypackage; $obj = new AnyObj(); where AnyObj type is not defined, but in XS I want to check the type database (UNO) and see if the type exists and create the new object type dynamically. Right now it will give compile error. I have done this with methods, for instance the object AnyObj is defined but none of the methods are defined, so I use autoload mechanism so: use mypackage; $obj = new AnyObj(); $ret = $obj-callMyMethod(); In my XS, I can define an AUTOLOAD method and check the (UNO) object to see if the method exists and forward the call accordingly. If you want more details on how I do this, you can checkout the Perluno project (http://perluno.sourceforge.net/) I took a look - and on the current vote for Struct I don't like any of the options - just like a real election ;-) my $obj = new Struct('Property', m1 = 1); would be my choice (i.e. nearly like 1st option but without the anon array. On the topic in hand you could auto-create classes if you were willing to change you invocation to: $obj = new UNO AnyObj = args; Now UNO::new can so whatever you want. It can also auto-create classes as UNO::AnyObj and avoid conflicts. package UNO; sub new { my ($class,$subclass,@args) = @_; no strict 'refs'; unless (exists ${$class::}{$subclass}) { @{${class}::${subclass}::ISA} = ...; # call class into being and set is base class(es). } return ${class}::$subclass-new(@args); } The above is of course possible in XS code too (possibly easier as the clever quoting is not required and you can use the various GV routines.) But while we are here - beware that the method Class syntax is error prone Class::-method e.g. Uno::-new(AnyObj = args); is much more robust.
Re: return value from XSUB mysteriously disappearing on second invocation
Jan Dubois [EMAIL PROTECTED] writes: On Sun, 07 Sep 2003 09:49:32 +0200, Tassilo von Parseval [EMAIL PROTECTED] wrote: Hi there, this is the strangest thing I've ever encountered so far with XS. To me it looks like a very obscure bug in perl, but hopefully it's not. The Perl examples actually use autobox, but the very same behaviour shows up when using a pure functional interface: I have a very basic C function that triggers a Perl callback: SV * call_Pslice (const char *func) { SV *res; dSP; ENTER; SAVETMPS; PUTBACK; (void)call_pv(func, G_SCALAR); SPAGAIN; res = newSVsv(POPs); PUTBACK; FREETMPS; LEAVE; return sv_2mortal(res); } You are missing a PUSHMARK(xxx) call in here. The call_pv() will pop your callers frame from the stack, and you caller doesn't seem to adjust for it. Two more unrelated notes: 1) You call sv_2mortal() on your result without checking if the result has the SvREADONLY bit set. If the sub can return undef, you may be modifying the refcount of an immortal, which doesn't matter in most cases as it starts with a refcount of 2**31, but is still bad style (IMO). I am not that bothered by that style issue. A related issue is that the value POPs-ed was a return value which would have been just fine a 'res' - if you removed the SAVETMPS/FREETMPS which will free it. 2) Calling call_xxx() without G_EVAL often doesn't work correctly when your Perl sub can die(). Maybe it is just cargo cult, but I've been bitten by this one too many times and now always specify G_EVAL and check SvTRUE(ERRSV) myself to handle exceptions myself. This has (I think) finally been fixed - but only recently. Stick with the cargo-cult for portability.
Re: return value from XSUB mysteriously disappearing on second invocation
Tassilo Parseval [EMAIL PROTECTED] writes: I was once more thinking about this PUSHMARK/PUSHBACK issue. perlapi.pod described them as opening and closing brackets for the arguments. If I leave those off altogether, shouldn't then simply the current @_ be passed on to the callback? This would be extremely handy in my case since the arguments for the callback are exactly those of the XSUB originally called. Therefore, I shouldn't need to re-populate @_ (at least not in theory). But that is not how it works ;-) Which is not to say you can't re-use caller's args - but you need to do a PUSHMARK because XSUB (or perl) is going to pop one. I think something like PUSHMARK(ORIGMARK); would do what you need. You can also add G_NOARGS to flags of the call_sv() but if I recall correctly that isn't a good idea if calling an XSUB (can't remember why...) See Lperlcall It worked like this for the callback that did not modify $_[0], No it didn't - you just did not notice the damage ... but not properly for the other one. 2) Calling call_xxx() without G_EVAL often doesn't work correctly when your Perl sub can die(). Maybe it is just cargo cult, but I've been bitten by this one too many times and now always specify G_EVAL and check SvTRUE(ERRSV) myself to handle exceptions myself. This has (I think) finally been fixed - but only recently. Stick with the cargo-cult for portability. Ok, I take your word on that and change things accordingly. Tests with 5.8.1, 5.6.1 and 5.00503 suggested that they all behave identical, but those weren't very complicated callbacks that I used. You only see the problem if the callback dies. Tassilo
Re: Help with variable number of args
Tassilo Parseval [EMAIL PROTECTED] writes: On Wed, Sep 17, 2003 at 11:39:54AM +1000 Dave Horsfall wrote: Pardon me if this is a FANQ (Freq. Asked Newbie Question), but I cannot find any references to what I want to do. I'm porting some legacy Perl/C code; it was originally done under Perl3 (hacked into the function table), thence Perl4 (via userinit() etc). I have the dubious honour of converting it into Perl5/XS. Most Perl/C calls take a variable number of string arguments, and this is where I'm coming unstuck. I've studied both perlxs and perlxstut until I'm practically dreaming XS, but I still cannot find a clear answer. Let's take an example of a user-defined Perl function: $return = uni_access(record, key1, key2); I don't think you need C_ARGS for that. Your XSUB should begin like this (for instance): int uni_access(record, ...) char *record; /* const char * may not be in typemap */ PREINIT: char **args; register int i; CODE: New(1, args, items-1, char*); for (i = 1; i items; i++) *args++ = SvPV_nolen(ST(i)); /* now you have key1 in args[0] and key2 in args[1] */ ... RETVAL = bla(); OUTPUT: RETVAL I implemented the XS stuff as a callable C library, but I have the freedom to change it (and had to, anyway). If you tell us how the perl4 code worked we may be able to figure out what to do. So you can see my dilemma; I need to tell the underlying C code how many arguments there are (I cannot change the Perl calls). Essentially, when working with variadic argument lists, you have the special variable 'items' telling you how many arguments were passed. You can then use ST(i) (or one of the POP? macros) to access the scalar Don't use POP macros - use ST(i). variables lying on the stack. You can find more on that in perlxs.pod. See Variable-length Parameter Lists. Tassilo
Re: Help with variable number of args
Tassilo Parseval [EMAIL PROTECTED] writes: On Wed, Sep 17, 2003 at 05:25:57PM +0100 Nick Ing-Simmons wrote: Tassilo Parseval [EMAIL PROTECTED] writes: On Wed, Sep 17, 2003 at 11:39:54AM +1000 Dave Horsfall wrote: So you can see my dilemma; I need to tell the underlying C code how many arguments there are (I cannot change the Perl calls). Essentially, when working with variadic argument lists, you have the special variable 'items' telling you how many arguments were passed. You can then use ST(i) (or one of the POP? macros) to access the scalar Don't use POP macros - use ST(i). What is wrong with these macros? I use them quite often and now that you mention it I am interested to know what might be the problem with them. The XS API using ST() and XSRETURN() uses the stack globals directly. The POP macros use a local-cached sp and need PUTBACK/SPAGAIN mixing the two is IMHO a bad idea. As XS is documented using ST() is is probably better to stick to that one. Tassilo
Re: Help with variable number of args
Dave Horsfall [EMAIL PROTECTED] writes: if ((abuf = fill_key(numargs, args, recnum)) == NIL(char)) The fill_key() function just took the Perl args and converted them into a structure used by the database. There's a whole bunch of code that I have left out, as I didn't want to overwhelm this list, and I didn't know which bits were relevant :-) fill_key() ! That is the bit that is equivalent to the problem you had surely? - send just to me if you like Then the perl5 version looks like this: /* C-code part of XS file */ static char * fill_key(int numargs, SV **args, recnum) { ... /* code similar to your perl4 stuff */ } /* Now XS part proper */ MODULE ... int uni_acckey(...) CODE: { int recnum; char *abuf = fill_key(items,ST(0),recnum); if (abuf == NULL) { return -1; /* or croak or XS_RETURN_UNDEF or whatever */ } return acckey(recnum,abuf); } OUTPUT: RETVAL It this really is a data-base it is probably also worth looking at DBI module (which is a meta-interface to true databases) or other DB modules like DB_File which map key/value databases onto perl's hashes via tie.
Re: Difference bewteen SvPV_nolen() and SvPVbyte_nolen(), and how to get SvPVbyte_nolen() used?
[EMAIL PROTECTED] writes: Probably a newbie question. I had to modify a SvPV_nolen() to SvPVbyte_nolen() to get some code to work properly. What is the difference between SvPV_nolen() and SvPVbyte_nolen()? SvPV_nolen() returns char * to string part of a scalar in its current encoding state. SvPVbyte_nolen() down-grades characters in range 0x80..0xFF which happen to have become UTF-8 encoded back to bytes first, by calling sv_utf8_downgrade(sv,0) That function is accessable to perl as : utf8::downgrade($scalar,$failok) So you could call that from perl before calling your XS. How do I get SvPVbyte_nolen() used for a parameter instead of SvPV_nolen()? If the type of a parameter is T_PV in typemap, I get SvPV_nolen() for the parameter. What type should I use to get SvPVbyte_nolen() instead? Hmm, nothing in the standard typemap so you need a custom one: - unsigned char * T_BYTE INPUT T_BYTE $var = ($type)SvPVbyte_nolen($arg) OUTPUT T_BYTE do { sv_setpv((SV*)$arg, $var); SvUTF8_off((SV *) arg); } while (0) - Or you could write your XS to accept an SV and call the right things in the CODE: section.
Re: Repost: [Fwd: Returning a list from an XSUB]
Steve Hay [EMAIL PROTECTED] writes: Any comments on this, anyone? - Steve Original Message Subject: Returning a list from an XSUB Date: Mon, 08 Sep 2003 15:05:20 +0100 From: Steve Hay [EMAIL PROTECTED] To:[EMAIL PROTECTED] Hi, I have an XSUB that calls a C function to get three integers, and then returns them (in list context). In scalar context it just returns a Boolean to indicate whether the C function succeeded or not. It currently looks like this: void my_func() PREINIT: I32 gimme; int one, two, three; PPCODE: gimme = GIMME_V; if (My_Func(one, two, three) == 0) { if (gimme == G_SCALAR) { XSRETURN_YES; } else if (gimme == G_ARRAY) { EXTEND(SP, 3); PUSHs(sv_2mortal(newSViv(one))); PUSHs(sv_2mortal(newSViv(two))); PUSHs(sv_2mortal(newSViv(three))); } } else { if (gimme == G_SCALAR) XSRETURN_NO; else if (gimme == G_ARRAY) XSRETURN_EMPTY; } I have a few questions about this: - Am I correct in just ignoring the G_VOID case, or would it be better to return somehow immediately rather than waste time calling the C function (given that the C function has no side effects beyond setting the three integers)? Up to you whether you call the C function. I would be tempted to put in the extra else XSRETURN_EMPTY; for the void case. - Is the EXTEND(SP, 3) call correct for the 3 subsequent PUSHs() calls? I thought it was OK to call PUSHs() once without needing to call EXTEND(SP, 1), You can in general push as many return values as you had args + 1 Currently when called from perl code you will I think get an extra slot for method calls. If you ever get called by someone elses XS code it isn't clear you will get a free push, so it is good practice to EXTEND to what you need. so perhaps I should only call EXTEND(SP, 2) when I have 3 values to return? 3 is correct - it is how many you want to push, perl doesn't know context of EXTEND macro, so can't allow for free pushes. - Do I need the else case of the main if block at all? Presumably just falling off the end of the XSUB when the C function failed would achieve the same thing? Or is it better style to code it explicitly as above? - Are the XSRETURN_* macros OK in a PPCODE section? PPCODE sections normally PUSHs their args onto a perl stack which has been unwound to point at ST(0) slot. It is possible that XSRETURN_NO/XSRETURN_YES might be confused by that. You could use a CODE: version as you know the return counts in advance. The Perl manpages seem to say it's OK, but I read something somewhere (can't remember where) that it wasn't a good idea because the C code generated contains return statements in a void() subroutine. All XSes are void subroutines. XSRETURN_ just do various perl-stack twiddling then return in C. void my_func() CODE: { I32 gimme = GIMME_V; int one, two, three; if (My_Func(one, two, three) == 0) { if (gimme == G_SCALAR) { XSRETURN_YES; } else if (gimme == G_ARRAY) { EXTEND(SP, 3); ST(0) = sv_2mortal(newSViv(one)); ST(1) = sv_2mortal(newSViv(two)); ST(2) = sv_2mortal(newSViv(three)); XSRETURN(3); } else { XSRETURN_EMPTY; } } else { if (gimme == G_SCALAR) XSRETURN_NO; else XSRETURN_EMPTY; } }
Re: just want to confirm something
[EMAIL PROTECTED] writes: if I have a function foo() and there is a XS wrapper, int foo() CODE: perl_foo() ..the perl_foo() is created automatically, it is litterally perl's version of foo()? No - perl_foo() is NOT created automatically. xsubpp could strip the prefix for you - avoiding the need for a CODE: section but does NOT provide the prefixed function. The reason I ask is I was looking at the XS interface for des_crypt(), and saw perl_des_crypt called within the XS wrapper. If you look elsewhere in the .xs file (probably above the MODULE line or perhaps in a .h file) you should find the definition of perl_des_crypt.
Re: Specifying LIBS
Dave Horsfall [EMAIL PROTECTED] writes: I must be misreading the documentation or something... Perl 5.8.0, MakeMaker 6.03 I'm trying to specify a set of libraries like this in Makefile.PL: 'LIBS' = ['-L/usr/unify/lib -ld1.a -ld2.a -lx.a'] (where libd1.a etc live under /usr/unify/lib) and I get this: Note (probably harmless): No library found for -ld1.a Note (probably harmless): No library found for -ld2.a Note (probably harmless): No library found for -lx.a The 'probably harmless' may be true for perl core stuff but seldom is for extensions. The libraries do not appear in the Makefiles (except as a comment). What am I doing wrong? Adding the .a LIBS' = ['-L/usr/unify/lib -ld1 -ld2 -lx']
RE: interfacing to (v)sprintf type things that expect varargs
Buzz Moschetti [EMAIL PROTECTED] writes: I had worked up something for HPUX and SunOS some years back. I will post if folks are interested. Thought this might be a standard in the XS arena by now. Saddly this is very hard. You say HPUX and SunOS, but you probably mean HP PA/SPARC. What C's ... does is CPU architecture specific not OS related. (See GCC's stdarg.h support to see the mess from the other side.) On some machines it is impossible to fake a ... call from C e.g. those where 1st few args are always passed in machine regs. Other machines where ... forces all args to be passed on C call stack are a little easier. You can usually fake a va_list so if the is a vffedit(char *fmt, va_list ap) available then with some pain and a lot of processors specific hackery you can build an ap and call that. There is package ffcall which has done most of the hard work. -Original Message- From: Dirk Koopman [mailto:[EMAIL PROTECTED] Sent: Friday, October 03, 2003 8:37 AM To: Perl XS Mailing List Subject: interfacing to (v)sprintf type things that expect varargs Subject says it all really. I have a number of vararg based routines that accept a number of optional arguments. Given that I know how to get these values from the stack (fortunately [most of the time] I know what they are), do you have any suggestions as to how I can reassemble the actual program stack from the perl stack so that I can call these routines in C. For example the perl XS prototype:- int ffedit(fmt,...) char *fmt; That needs to translate to the C function: int ffedit(char *fmt, ...) in real life. If ffedit's behaviour is similar to printf's then same technique as used in perl core for print can be used. This is (roughly): Incrementally parse fmt string your self to find out a type. Convert one perl arg to the required type in a switch() on type. In each case: of the switch call C routine with fragment of fmt string and one arg. Loop till you get to the end of the fmt string. Dirk *** Bear Stearns is not responsible for any recommendation, solicitation, offer or agreement or any information about any transaction, customer account or account activity contained in this communication. ***
Re: Returning a pointer to local data
Steve Hay [EMAIL PROTECTED] writes: What's the best way to have an XSUB return a string (char *) when the caller doesn't know how big that string will be? At a mortal string SV: void my_xsub() CODE: { ST(0) = sv_2mortal(newSVpv(string,strlen(string)); XSRETURN(1); } I like that style because as soon as you have created the SV you know perl has a copy and can cleanup. You should get the same effect via char * my_xsub() CODE: { RETVAL = string; } OUTPUT: RETVAL or SV * my_xsub() CODE: { RETVAL = sv_2mortal(newSVpv(string,strlen(string)); } OUTPUT: RETVAL In C a function can't return a pointer to a function-static variable, but in Perl you can get away with a function returning a reference to a function-scoped lexical variable. Can you do (fake) this sort of thing in an XSUB? Presumably, if I malloced the space that I'm returning a pointer to then it needs freeing up afterwards, but not before Perl has copied it somewhere! Is a CLEANUP section good for that? As a (silly) test, the following XSUB seems to work, but I'd just like to check that this is alright. char * hello() PREINIT: char*text; CODE: Newz(0, text, 13, char); strcpy(text, Hello, world); RETVAL = text; OUTPUT: RETVAL CLEANUP: Safefree(text); It's a cheat really, because the return value is not a pointer to local data -- it's a pointer to a copy of it, the malloced local data itself being freed again -- but at least the caller doesn't have to provide the space for the data to be copied to. Perl never does provide space. In cases like this where you are going to Newz() the space anyway you can avoid an extra copy when returning the value with sv_usepvn() Is there a better way to have a Perlish calling style like $text = my_xsub(); when the caller doesn't know in advance how big that $text is going to be? Thanks, - Steve
Re: Returning a pointer to local data
Tassilo Parseval [EMAIL PROTECTED] writes: Is this certain that my_xsub() returns a mortal? No - but it needs to return something which something will eventually free. When looking into the generated C code, I see: { char *RETVAL; RETVAL = string; sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; } XSRETURN(1); Is TARG treated as a mortal? No TARG isn't mortal. It is an SV which hangs off the OP in the parse tree (I think). It eventually gets free-d when that part of parse tree is destroyed. TARG avoids the create/destroy overhead of mortals, but has side effect that if you assign a BIG string to it the memory hangs around ready for next time. (The TARG stuff is new-ish and I learnt my XS before it existed so I tend to forget about it.) I wasn't able to figure that out with a few greps through the Perl source. Tassilo
Re: Returning a pointer to local data
Sisyphus [EMAIL PROTECTED] writes: Tassilo von Parseval wrote: On Thu, Oct 30, 2003 at 08:02:53PM +1100 Sisyphus wrote: Nick Ing-Simmons wrote: SV * my_xsub() CODE: { RETVAL = sv_2mortal(newSVpv(string,strlen(string)); } OUTPUT: RETVAL As regards that, Nick - is the 'sv_2mortal' part necessary ? I thought *not* - but I'm sometimes wrong :-) It is. If you have code like { my $var = my_xsub(); ... } and want $var to be cleaned up when it falls out of scope, you have to make it a mortal. Mortals are just variables that clean up themselves when their reference count goes to zero. I still question that - and hope that in so doing I don't raise your anger. (That's not what I'm trying to do :-) You are right. The sv_2mortal _IS_ needed in the void my_xsub() CODE: { ST(0) = sv_2mortal(newSVpv(string,strlen(string)); XSRETURN(1); } case. But it is inserted for you SV * return case: { RETVAL=newSV...; } #line 25 Foo.c ST(0) = RETVAL; sv_2mortal(ST(0)); } XSRETURN(1); } But if I run as Inline C code: SV* dumb(char * s) { return newSVpv(s, 0); } With perl code: my $d = 'a' x 100; for(0..1000) { my $string = dumb($d); print .; sleep 1; } Then I don't observe any memory leak. I can see the memory usage jump when the program starts, but it remains steady as the loop goes through its iterations. If you are correct, I would have expected to see memory usage increase every second. My view that 'sv_2mortal' is not required in this instance is also supported by some sample code and discussion contained in the fine book by Jenness and Cozens. If I'm missing something I hope someone can point at the fallacy(s) in my thinking. Cheers, Rob
Re: Returning a pointer to local data
Tassilo Parseval [EMAIL PROTECTED] writes: On Thu, Oct 30, 2003 at 11:13:47AM + Nick Ing-Simmons wrote: Sisyphus [EMAIL PROTECTED] writes: Tassilo von Parseval wrote: It is. If you have code like { my $var = my_xsub(); ... } Mortals are just variables that clean up themselves when their reference count goes to zero. I still question that - and hope that in so doing I don't raise your anger. (That's not what I'm trying to do :-) You are right. The sv_2mortal _IS_ needed in the void my_xsub() CODE: { ST(0) = sv_2mortal(newSVpv(string,strlen(string)); XSRETURN(1); } case. But it is inserted for you SV * return case: { RETVAL=newSV...; } #line 25 Foo.c ST(0) = RETVAL; sv_2mortal(ST(0)); } XSRETURN(1); } Hmmh, indeed. I peeked at xsubpp and it looks as though this is a special case: elsif ($expr =~ /^\s*\$arg\s*=/) { # We expect that $arg has refcnt =1, so we need # to mortalize it! eval print qq\a$expr\a; warn $@ if $@; print \tsv_2mortal(ST(0));\n; print \tSvSETMAGIC(ST(0));\n if $do_setmagic; } The typemap entry for 'SV*' expands to $arg = $var However, doing char * my_xsub() CODE: RETVAL = strdup(string); OUTPUT: RETVAL will leak since the returned SV is not mortalized (and the copy of 'string' thus never freed). That leaks for strdup() reasons, not for SV leak: #line 18 Foo.xs { RETVAL=strdup(string); } #line 47 Foo.c sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; } XSRETURN(1); } That does not leak as it uses the TARG scheme. I think this is one good reason for sticking to one style of handling return values in XS since they differ quite significantly. Agreed. I prefer the explicit manipulation of the return stack by feeding it my manually constructed SV's. So do I. That way, I can be sure that each scalar has the characteristics it is supposed to have.
Re: Returning a pointer to local data
Sisyphus [EMAIL PROTECTED] writes: Nick Ing-Simmons wrote: The sv_2mortal _IS_ needed in the void my_xsub() CODE: { ST(0) = sv_2mortal(newSVpv(string,strlen(string)); XSRETURN(1); } case. But it is inserted for you SV * return case: { RETVAL=newSV...; } #line 25 Foo.c ST(0) = RETVAL; sv_2mortal(ST(0)); } XSRETURN(1); } Case a: void my_func() I return a mortal SV via the stack. Case b: SV * my_func() I return an SV directly. Let's see ... I'm being told that Case a and Case b are, wrt what gets executed, exactly the same (or very nearly so) right ? Yes - there are some {} in different places but guts is essentially identical. In both cases, a mortal SV is being returned via the stack ? - which would go some way to explaining the similar performance of both cases :-) And the Case c: char *my_func() uses the TARG style - which is different. What's 'Foo.c', btw ? Output of xsubpp for a Foo.xs I slung together to see what got generated.
Re: Returning a pointer to local data
Steve Hay [EMAIL PROTECTED] writes: I understand the second case there -- when the xsub is called as hello(1) -- but that leaves me wondering what ST(0) was in the case where the xsub was called without arguments. It is a stack - a hunk of memory. So if you don't have any args one it is: - the SV returned by last thing caller called, or - if that didn't return anything then 1st arg of last call, or - some arg passed/returned by someone or - garbage that will give you a segfault if nothing has been called Nth arg of the caller. Presumably I should therefore rewrite the above as: void hello() PREINIT: char*chartext; CODE: Newz(0, chartext, 13, char); strcpy(chartext, Hello, world); ST(0) = newSV(0); sv_usepvn(ST(0), chartext, 13); XSRETURN(1); to be sure of what ST(0) really is. Yes. By the way what is the reason you do a PREINIT which does no init rather than CODE: { char *chartext; ... } ? After a quick skim-read of the perlcall manpage I tried writing another xsub called callhello() that calls the hello() xsub above and simply returns whatever hello() returned: void callhello() CODE: dSP; PUSHMARK(SP); PUTBACK; // not essential with no args call_pv(Foo::hello, G_SCALAR); SPAGAIN; // always required ST(0) = POPs; PUTBACK; // Not essential if returning next ... XSRETURN(1); However, when I call that from Perl (my $greeting = Foo::callhello()) I find that callhello() returned 1 rather than hello. You need in general the PUTBACK/SPAGAIN when stack pointer has changed. In particular calling something may grow the stack. As POPs changes stack pointer it is perhaps less risky to your sanity to do things in stages: call_pv(...); // stack may move SPAGAIN;// Get current stack val = POPs; // stack changes PUTBACK;// update stack ST(0) = val; XSRETURN(1); (Am I correct in thinking that I don't require the ST(0) = newSV(0) bit this time since I'm assigning something else to ST(0) anyway rather than telling an already extant ST(0) to use a char * elsewhere.) I then tried again, this time passing an argument to the hello() xsub (after changing it as before to accept arguments): void callhello() CODE: dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(1))); PUTBACK; call_pv(Foo::hello, G_SCALAR); ST(0) = POPs; FREETMPS; LEAVE; XSRETURN(1); This time callhello() works, returning Hello, world. This is most likely because this time YOUR XPUSHs grew the stack, not the call, so SP is still the value you PUTBACK. But there is a new snag with that code. You have added a SAVETMPS/FREETMPS pair. So if Foo::hello had used the 'mortal' style the SV you re-used will be free-d when you hit the FREETMPS, and callhello's caller would see an undef. Does this confirm my suspicion that the hello() xsub doesn't have a free item (ST(0)) on the stack when called from another xsub? As a further test I tried having hello() extend the stack by one to be safe if it is called with no arguments. Here's the new hello(): void hello(...) PREINIT: char*chartext; CODE: Newz(0, chartext, 13, char); strcpy(chartext, Hello, world); if (items == 0) { PerlIO_printf(PerlIO_stdout(), No args\n); EXTEND(SP, 1); } ST(0) = newSV(0); sv_usepvn(ST(0), chartext, 13); XSRETURN(1); However, when I called that from callhello() with no arguments, callhello() *still* returned 1 rather than Hello, world, so perhaps my suspicion is not confirmed after all, and I've buggered something else up instead! (The No args message was printed out, so the EXTEND(SP, 1) was definitely done.) - Steve
Re: Returning a pointer to local data
By the way what is the reason you do a PREINIT which does no init rather than CODE: { char *chartext; ... } ? I once fell foul of the problem described in the PREINIT entry in the perlxs manpage, namely: If a variable is declared inside a CODE: section it will follow any typemap code that is emitted for the input parameters. This may result in the declaration ending up after C code, which is C syntax error. I was very new to XS at the time (even newer than I am now ;), and was confused for ages by it. I've used PREINIT to declare all my variables ever since then just to play it safe. Is there a problem with using PREINIT all the time in this way? Don't know - but I tend to use {} after CODE: - which creates a new C block which can declare things. At this point I have: void hello(...) PREINIT: char*chartext; CODE: Newz(0, chartext, 13, char); strcpy(chartext, Hello, world); ST(0) = newSV(0); ST(0) = sv_newmortal(); // like above but does sv_2mortal for you sv_usepvn(ST(0), chartext, 13); XSRETURN(1); void callhello() PREINIT: SV *val; CODE: dSP; PUSHMARK(SP); PUTBACK; call_pv(Foo::hello, G_SCALAR); SPAGAIN; val = POPs; PUTBACK; ST(0) = val; PUTBACK; // this one is not necessary XSRETURN(1); So it seems that you can, after all, assign to ST(0) even when an xsub is called with no arguments from another xsub. I'm puzzled by that: I thought that before assigning to ST(0), ..., ST(n) you had to call EXTEND(SP, n + 1). Calling EXTEND(SP, n) would suffice when the xsub is called from Perl, but not when called from another xsub. In this case we are calling from another xsub; n is 0, so I thought I would have needed to call EXTEND(SP, 1) first. I think there is one free slot - but I may be wrong. There's one other problem too: The above code leaks if I call callhello() a million times over in a for loop. Where is the leak coming from? You haven't made its return value mortal. The SAVETMPS/FREETMPS was to have the (mortal) argument that I'm passing to Foo::hello free()'d; I'd forgotten that it free()'s any mortal return values as well. Here's the example with hello() returning a mortal SV * that has its own char * space: void hello(...) PREINIT: char*chartext; CODE: Newz(0, chartext, 13, char); strcpy(chartext, Hello, world); ST(0) = sv_2mortal(newSVpv(chartext, 13)); XSRETURN(1); void callhello() PREINIT: SV *val; CODE: dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(1))); PUTBACK; call_pv(Foo::hello, G_SCALAR); SPAGAIN; val = POPs; PUTBACK; ST(0) = val; PUTBACK; FREETMPS; LEAVE; XSRETURN(1); It does indeed result in callhello()'s caller getting undef. So how would I avoid coming a cropper like that? I want the arguments that callhello() passes to hello() to be freed before callhello() returns, but I don't want hello()'s return value to be free()'d then as well. This seems to work: ... call_pv(Foo::hello, G_SCALAR); SPAGAIN; val = newSVsv(POPs); PUTBACK; FREETMPS; LEAVE; ST(0) = sv_2mortal(val); PUTBACK; XSRETURN(1); Is that OK That moral equivalent of what perl does ... or is there a more efficient way to do this? Slightly. val = POPs; PUTBACK; SvREFCNT_inc(val); // save it from destruction FREETMPS; LEAVE; // now back in outer scope. ST(0) = sv_2mortal(val); XSRETURN(1); - Steve
Re: Perl XS help - XS won't return a hash of arrays
[EMAIL PROTECTED] writes: Hi Nick, my name is Doug Brann, and you don't know me. I'm sorry to be mailing this to you directly, but I've tried posting to the perl-xs newsgroup several times without success. It's the first time I've ever tried posting to a newsgroup, so I don't know if there is some problem with the news server, or the idiot trying to post (me, that is). If you don't have the time to answer this, if you would please forward it to the newsgroup, I'd be grateful. Anyhow, here's my problem: I have a perl script that is doing something like: %data = Reader::new(file); You are only passing file and not the class. Did you mean: %data = Reader-new(file); foreach (keys %data) { print ($_ is of type $data{$_}); } in the foreach block, the response is UNKNOWN, when I'm hoping it will say ARRAY. There are syntax errors in that - at least a missing . It I get the hash key out, but not the correct array type. When I try to access the array, I get fatal errors in the script. Here's a chunk of the offending xs code: void new (CLASS, filename) char *CLASS char *filename PREINIT AV *data = NULL; SV *sv = NULL; double *data_ptr; unsigned int count; unsigned int size; FILE = *file; char name[1024]; /* name is only 1023 long */ unsigned int i; PPCODE: if((file=fopen(filename, rb)) == NULL) { As you declared this as taking two args (CLASS and filename) and only passed one I would expect this to fail. printf(couldn't open %s\n, filename); XSRETURN_UNDEF; You would probably be better off with XSRETURN(0); // return empty list Otherwise you have done %data = (undef); } count = 0; name[1023] = '\0'; /*need a null terminator */ done = 0; while (feof(file)){ Surely you mean while (!feof(file)) ? /* read in the name */ fread(name, 1, 1023, file); You could look at the count of items returned and use 0 items rather than : if(feof(file)) { // wrong sense again. continue; } /* now get the size */ fread(size, 4, 1, file); fread(size, sizeof(size), 1, file); // would be safer. /* get some memory and the data */ data_ptr = (double*)safemalloc(sizeof(double) * size); if(data_ptr == NULL) { printf(couldn't get memory); XSRETURN_UNDEF; } fread (data_ptr, sizeof(double) * size, 1, file); fread(data_ptr, sizeof(double), size, file); // intended use of fread data = (AV*) sv_2mortal((SV*)newAV()); I don't think the AV should be mortal... av_extend(data, size); for (i = 0; i size; i++) /* boy I wish I could fread the data straight into */ /* an AV array without this step !! */ // You could read it into a pack-ed string. av_store(data, i newSVnv(data_ptr[i])); } XPUSHs(sv_2mortal(newSVpv(name, 1024))); I am unclear about the length there - is this a normal C string? XPUSHs(sv_2mortal(newRV_noinc((SV*)data))); The RV should be mortal, but as AV is as well, the AV will be freed from under it... count++; safefree(data_ptr); } /* while */ XSRETURN(count *2); Can you help me? I've looked in the archives of the newsgroup and found a similar problem, and tried duplicating the code, to no avail. The XS/perl parts look okay. It is your use of stdio that is dodgy. specifically I read Adding an array as a hash entry - Cloutier, Christian Date: 05-29-03 11:07 Thanks in advance for any help you can give. -Doug Brann This email was sent from Netspace Webmail: http://www.netspace.net.au
Re: GTop: undefined symbol: glibtop_global_server
Eamon Daly [EMAIL PROTECTED] writes: Hi, everyone. I'm in a minor panic trying to compile GTop on a Red Hat Linux 7.2 box. When I compile, I get the error: Please specify prototyping behavior for Server.xs (see perlxs manual) That does not _need_ fixing. Subsequently, running anything with use GTop results in: Can't load '/usr/local/lib/perl5/site_perl/5.8.1/i686-linux/auto/GTop/GTop.so' for module GTop: /usr/local/lib/perl5/site_perl/5.8.1/i686-linux/auto/GTop/GTop.so: undefined symbol: glibtop_global_server at /usr/local/lib/perl5/5.8.1/i686-linux/DynaLoader.pm line 229. I've tried using several different libgtop libraries (1.0.6, 1.0.12, 1.0.13) and they all yield the same build and execute errors. I have no idea what libgtop is - but if they all fail, chances are it isn't them, but the way you are (not) linking them. Does nm -A .../libgtop* | grep glibtop_global_server show the symbol ? Does Makefile.PL step give any diagnostics? What does generated Makefile show for LIBS = ? Who owns the GTop module these days? (STAS copied as he owns it in CPAN). The Makefile.PL is quite complex, and the README terse. It looks like you need glib-config in your path and/or several ENV variables set for it to build.
XSRETURN(Function()) risky : Nasty segfault in Tk fixed
To let Tk list know a major gotcha blocking Tk release is fixed. Thanks to Steve Lide for the guest account on his G5 machine to track this! To let perl-xs list know even I am human and do dumb things ... void WidgetMethod(widget,name,...) SV *widget; SV *name; CODE: { Lang_CmdInfo *info = WindowCommand(widget, NULL, 1); XSRETURN(Call_Tk(info, items, ST(0))); } Looks neat and tidy - but is fatally flawed. XSRETURN macro is basically THE_PERL_STACK_POINTER += Something. On Steve's G5 - that gets compiled as Get PERL_STACK_POINTER call function which returns value add Set PERL_STACK_POINTER The snag is that when function which returns value is a perl callback it can move the stack. So after above the stack pointer is pointing into an old stack which has now been free'd and re-used = CORE. Changing it to: void WidgetMethod(widget,name,...) SV *widget; SV *name; CODE: { Lang_CmdInfo *info = WindowCommand(widget, NULL, 1); IV count = Call_Tk(info, items, ST(0)); XSRETURN(count); } Fixes the problem.
Re: XSRETURN(Function()) risky : Nasty segfault in Tk fixed
Marcus Holland-Moritz [EMAIL PROTECTED] writes: How about also fixing the source of the problem? Already suggested that to p5p. But that isn't going to help the folk with ActivePerl or RedHat or SuSE or ... --- XSUB.h.orig Wed Dec 10 20:39:37 2003 +++ XSUB.h Wed Dec 10 20:43:26 2003 @@ -193,7 +193,8 @@ #define XSRETURN(off) \ STMT_START { \ - PL_stack_sp = PL_stack_base + ax + ((off) - 1); \ + IV tMpOfF = off;\ + PL_stack_sp = PL_stack_base + ax + (tMpOfF - 1);\ return; \ } STMT_END -- Marcus
Re: catching Perl_croak
Marcus Holland-Moritz [EMAIL PROTECTED] writes: I am trying to debug the Zeta perl module which fails when calling a c sub by the name of Zeta::_present the call to the Zeta:_present is as follows: eval{ ($status, $reason, $howmany, @records) = Zeta::_present ($unique, $resultset, $items, $start, $esn, $recstx, $Zeta::TIMEOUT);}; if($@){ return 0; } the call to Zeta::_present does not return at all. Well I have never heard of Zeta either - but last arg seems to be a timeout - what value is it (in what units) and did you wait that long? Mmmh, never heard of Zeta before (and it's not on CPAN). Googleing showed up a couple of dead links. However, the above code *should* work. If Zeta::_present really calls Perl_croak() (did you check using a debugger?), it should return and immediately leave the eval scope. If the call doesn't return at all, where does it hang (again, a debugger might help to find that out)? What happens without the eval { } block? BTW, which version of perl are you using (Output of perl -V)? In addition: where can I find the actuall code of the c subs that are used by the perl module? From http://lists.w3.org/Archives/Public/www-zig/2000Jun/0021.html : The biggest problem with the ZETA Perl Module is the inclusion of system-dependent libraries that are still copyrighted by Finsiel S.p.A. They are currently available in binary format only and are included within the module. I never obtained the permissions to release the source code under GPL and I stopped to ask :-( So I guess you won't find the code at all... -- Marcus Dana -Original Message- From: Marcus Holland-Moritz [mailto:[EMAIL PROTECTED] Sent: Monday, December 22, 2003 5:26 PM To: Dana Sharvit - M Cc: [EMAIL PROTECTED] Subject: Re: catching Perl_croak Hi Dana, I have a perl program that is call a c sub , the c subs issus a Perl_croak. How can I catch that in the perl program, I tried with eval but it does not work. You can definitely catch a call to Perl_croak() with eval. What exactly do you mean by it does not work? What happens? What do you think should happen? Can we see your code and what you expect it to do? -- Marcus
Re: Not properly XS..
Alberto Manuel =?ISO-8859-1?Q?Brand=E3o_Sim=F5es?= [EMAIL PROTECTED] writes: Only to be sure, this means that when we use $/ with something other than \n Perl will slurp all the file to memory? No. It slurps till it finds $/ value. Each line you get with ends with $/ (if possible) i.e. in your case it is as if perl is matching m#^.*?/tu$# to build lines. So if you file isn't really separated like that large chunks of it may be read into memory. So $/ = /tu; my $header = ; Is going to read till it finds a '/tu' Thanks Alberto On Mon, 2004-01-05 at 21:24, Billy Patton wrote: Albert, try this while () { s!header([^/]+)/!header$1/header!; ... print; } Process a single line at a time, not the whole file. ___ _ ___ __ __ / _ )(_) / /_ __ / _ \___ _/ /_/ / ___ / _ / / / / // / / ___/ _ `/ __/ __/ _ \/ _ \ //_/_/_/\_, / /_/ \_,_/\__/\__/\___/_//_/ /___/ Texas Instruments ASIC Circuit Design Methodlogy Group Dallas, Texas, 214-480-4455, [EMAIL PROTECTED] On Mon, 5 Jan 2004, Alberto Manuel Brando Simes wrote: but maybe you guys(hope this is the correct way :-/) know how to help me... I have this simple script: $/ = /tu; my $header = ; # header/ - header/header $header =~ s!header([^/]+)/!header$1/header!; # body version... - body $header =~ s!body[^]+!body!; # tmx version - tmx version=1.1 $header =~ s!tmx version[^]+!tmx version=1.1!; # srclang - srclang=foo if ($header =~ m!(xml:)?lang=(['])([^']+)\2!) { $lang = $3; $header =~ s!srclang=(['])[^']+\1!srclang=$lang!; } $header =~ s/xml:lang/lang/g; # xml:lang - lang print $header; while() { s/xml:lang/lang/g; print } Basically, a filter working on chunks (about 300bytes chunks). The problem is that I cannot process a 400MB file, because of out-of-memory. What is wrong? how can I solve it? Thanks a lot, and sorry for being a little OT. Alberto
Re: extending SP disabling warnings in an XSUB
Tassilo Parseval [EMAIL PROTECTED] writes: Hi, two little questions this time. 1) When I return multiple values from an XSUB by doing a ST(0) = sv_newmortal(...); ST(1) = sv_newmortal(...); XSRETURN(2); do I have to do a prior EXTEND(SP, 2)? Currently I am not doing it and it seems to work fine. It depends how many args you are passed. If you have at least two args then at least two slots exist. But as EXTEND is a macro and cheep if it doesn't need to do anything you may as well put it in. 2) For some parameter parsing, I'd like to get rid of a few warnings that happen when I do a 'SvIV(ST(n))' and ST(n) is not SvIOK but rather a string or so. SvIV() will upgrade a string that looks like a number (and indeed there is a function looks_like_a_number() you can use.) I didn't find an interface to the warnings and so poked around a little in warnings.h. Right now I'm doing it this way: CODE: { SV *oldwarn = PL_curcops-cop_warnings; PL_curcops-cop_warnings = pWARN_NONE; ... PL_curcops-cop_warnings = oldwarn; XSRETURN_YES; } Is there a clean and commonly accepted way of doing it? I don't know - the above is exactly what Tk does in the one spot it bothers to do anything. I tend to code defensively so warnings go away. And if not, is the above reliable? The risk is if what you show as '...' can croak() - then perhaps something to restore the SV would be appropriate. As this is an SV there is an save_item() to do the job (I think - I always have to read scope.c for the save_xxx() stuff). TIA, Tassilo
Re: Segfaults from XS code
Tels [EMAIL PROTECTED] writes: -BEGIN PGP SIGNED MESSAGE- Moin, I have written a (simple?) routine in XS that uses the GMP library to calculate the modular inverse. When running a small test file, it segfaults at the end of the testfile like this: ... ok 253 ok 254 ok 255 Segmentation fault Running it under valgrind gives the text below. Here is the XS code. I have tried several variations, but to no avail (I really don't know what I do, maybe I should first read the Perl Embedding book fully :) Does somebody spot something wrong or something I could do better? valgrid is complaining about XS_Math__BigInt__GMP_DESTROY can we see that please? The routine basically only returns (undef,undef) (but not in my testcase!) or (4404, '+'). The case of ($somenumber, '-') shouldn't happen (and does not in my testcase, anyway). void _modinv(class,x,y) SV* class mpz_t* x mpz_t* y PREINIT: int rc, sign; SV* s; PPCODE: rc = mpz_invert(*x, *x, *y); EXTEND(SP, 2); /* we return two values */ if (rc == 0) { /* inverse doesn't exist, return value undefined */ PUSHs ( PL_sv_undef ); PUSHs ( PL_sv_undef ); } else { /* inverse exists, get sign */ sign = mpz_sgn (*x); /* absolute result */ mpz_abs (*x, *x); PUSHs(sv_setref_pv(sv_newmortal(), Math::BigInt::GMP, (void*)x)); That is probably wrong. A pv is a char * and perl is going to do strlen() on it and strcpy() it into memory allocated by perl's New(). My guess is x is already malloc()'ed or C++ new'ed by mpz stuff. In such cases it is usual to use sv_setref_iv(...,PTR2IV(x)), and then have DESTROY function call the inner library's free() routine. If *x is a struct then it may also be apprpriate to put the struct as binary data in a PV - but there isn't a handy create-blessed-ref function to do that, you need to do it long-hand something like: SV *sv = sv_bless(new_RV(newSVpv(x,sizeof(*x))),gv_stashpv(..., TRUE)); (Trying to do that in one expression may be too rich for some compilers when all macros are expanded.) The other issue you _may_ be having is that *x came in from an SV (possibly tempoary). Unless *x is refcounted in mpz library you need get library to give you a new one to return from the XSUB to another perl SV, or change perl view of API to mimic the library's modify-in-place semantics. Otherwise both SVs will call DESTROY and try and free(x). if (sign = 0) { PUSHs ( PL_sv_undef ); /* result is ok, keep it */ } else { s = sv_newmortal(); sv_setpvn (s, -, 1); PUSHs ( s );/* result must be negated */ } } I tried to allocate a new GMP object and return a ref to that instead, but this is exactly the same segfault. Thank you in advance, Tels ok 255 ==5047== Invalid read of size 4 ==5047==at 0x41F090A5: __gmpz_clear (in /usr/lib/libgmp.so.3.3.2) ==5047==by 0x41ED12A1: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/ math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so) ==5047==by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl) ==5047==by 0x8060DCE: Perl_call_sv (in /usr/bin/perl) ==5047==Address 0x41D18D4C is 0 bytes inside a block of size 12 free'd ==5047==at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so) ==5047==by 0x41ED12A9: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/ math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so) ==5047==by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl) ==5047==by 0x8060DCE: Perl_call_sv (in /usr/bin/perl) ==5047== ==5047== Invalid read of size 4 ==5047==at 0x41F090AE: __gmpz_clear (in /usr/lib/libgmp.so.3.3.2) ==5047==by 0x41ED12A1: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/ math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so) ==5047==by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl) ==5047==by 0x8060DCE: Perl_call_sv (in /usr/bin/perl) ==5047==Address 0x41D18D54 is 8 bytes inside a block of size 12 free'd ==5047==at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so) ==5047==by 0x41ED12A9: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/ math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so) ==5047==by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl) ==5047==by 0x8060DCE: Perl_call_sv (in /usr/bin/perl) ==5047== ==5047== Invalid free() / delete / delete[] ==5047==at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so) ==5047==by 0x41F010BC: __gmp_default_free (in /usr/lib/libgmp.so.3.3.2) ==5047==by 0x41F090BB: __gmpz_clear (in /usr/lib/libgmp.so.3.3.2) ==5047==by 0x41ED12A1: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/ math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so) ==5047==Address 0x41D18D88 is 0 bytes inside a block of size 8 free'd ==5047==at 0x40028E01:
Re: extending SP disabling warnings in an XSUB
Tassilo Parseval [EMAIL PROTECTED] writes: The risk is if what you show as '...' can croak() - then perhaps something to restore the SV would be appropriate. That fortunately can't happen in this particular case. But om the future, I might need something more generic, so... As this is an SV there is an save_item() to do the job (I think - I always have to read scope.c for the save_xxx() stuff). A save_item(PL_curcops-cop_warnings); PL_curcops-cop_warnings = pPWARN_NONE; would automatically restore PL_curcops-cop_warnings upon leaving the XSUB? That would be pretty cool. With the save_xxx() stuff it I always have to look at code but yes, that will restore it on next LEAVE; Calling an XS does not normally give you an ENTER/LEAVE pair (this allows XS to do things like 'local' - scary but very occasionaly useful). If you don't have an ENTER/LEAVE pair in your code it is some caller's LEAVE.
Re: Segfaults from XS code
Tels [EMAIL PROTECTED] writes: -BEGIN PGP SIGNED MESSAGE- Moin, On Saturday 10 January 2004 19:22, Nick Ing-Simmons wrote: Tels [EMAIL PROTECTED] writes: -BEGIN PGP SIGNED MESSAGE- valgrid is complaining about XS_Math__BigInt__GMP_DESTROY can we see that please? ## # DESTROY() - free memory of a GMP number void DESTROY(n) mpz_t* n PPCODE: mpz_clear(*n); free(n); If it is in a SvPV then you don't call free(). Sorry, should have included it. Here is the typemap, too: mpz_t * MPZ INPUT MPZ if (sv_derived_from($arg, \Math::BigInt::GMP\)) { IV tmp = SvIV((SV*)SvRV($arg)); $var = ($type) tmp; } else croak(\$var is not of type Math::BigInt::GMP\) OUTPUT MPZ sv_setref_pv($arg, \Math::BigInt::GMP\, (void*)$var); The typemap is wrong. The OUTPUT side puts thing in SvPV the input side gets it from SvIV. Which is right depends on how mpz_t's are allocated. If they are malloc()ed then SvIV style is correct and you can use DESTROY as above with free(). But _something_ needs to make sure only one SV owns the mpz_t * and so free() only happens once. Alternatively if mpz_t is stored as opaque binary data in string part of SV (SvPV) then OUTPUT still isn't right as binary data will respond badly to being strcpy() to the PV, and INPUT is wrong as it is looking in wrong SV slot. Also in this case you don't need to free() as SvPV will be Safefree()'d by perl. This scheme works quite well with perl's SvREFCNT keeping track of when data can go. mpz_abs (*x, *x); PUSHs(sv_setref_pv(sv_newmortal(), Math::BigInt::GMP, (void*)x)); That is probably wrong. A pv is a char * and perl is going to do strlen() on it and strcpy() it into memory allocated by perl's New(). My guess is x is already malloc()'ed or C++ new'ed by mpz stuff. In such cases it is usual to use sv_setref_iv(...,PTR2IV(x)), and then have DESTROY function call the inner library's free() routine. If *x is a struct then it may also be apprpriate to put the struct as binary data in a PV - but there isn't a handy create-blessed-ref function to do that, you need to do it long-hand something like: SV *sv = sv_bless(new_RV(newSVpv(x,sizeof(*x))),gv_stashpv(..., TRUE)); (Trying to do that in one expression may be too rich for some compilers when all macros are expanded.) The typemap should do something like that, so I should be able just to copy it's code, right? You could copy its code if its code was correct. But to match input it should be sv_setref_iv(...,PTR2IV(x)) sv_setref_pv($arg, \Math::BigInt::GMP\, (void*)$var); Looks the same to me. (But the typemaps INPUT looks funny to my naive eyes..) The other issue you _may_ be having is that *x came in from an SV (possibly tempoary). Unless *x is refcounted in mpz library you need get library to give you a new one to return from the XSUB to another perl SV, or change perl view of API to mimic the library's modify-in-place semantics. Otherwise both SVs will call DESTROY and try and free(x). Thank you for your explanations. This is still a little bit over my head, I'll see if I can make heads or tail out of this tomorrow morning.
Re: relocation error
Chris Masters [EMAIL PROTECTED] writes: Hi All, I'm getting the following error when running some perl code (that calls functions in my XS module) after compiling and installing my perl-xs module: perl: relocation error: /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi/auto/My_XS_Module/My_XS_Module.so: undefined symbol: FunctionName I can compile and run C++ programs that use the C++ library (that I'm wrapping) and the FunctionName function OK. I have LIBS in Makefile.PL set as: 'LIBS' = ['-lMyStaticCLib -lm -lz -ljpeg -lpng -ltiff'], The order looks wrong - static libs need to be in right order probably -lMyStaticCLib -ltiff -ljpeg -lpng -lz -lm' but should be okay dynamic. Have you put libMyStaticClib.a in /usr/lib ? Do you need a -L to say where it is. What does nm -C libMyStaticClib.a | grep FunctionName say? If FunctionName is a C function have you declared it as extern C? Compiling XS with g++ means function names get mangled I also have CC set to point to g++ in Makefile.PL: $CC = 'g++'; And that does actually get used by Makefile ? If I do a ldd of My_XS_Module.so: ldd /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi/auto/My_XS_Module/My_XS_Module.so libz.so.1 = /usr/lib/libz.so.1 (0x40056000) libjpeg.so.62 = /usr/lib/libjpeg.so.62 (0x40064000) libpng12.so.0 = /usr/lib/libpng12.so.0 (0x40082000) libtiff.so.3 = /usr/lib/libtiff.so.3 (0x400a5000) libstdc++.so.5 = /usr/lib/libstdc++.so.5 (0x400e7000) libm.so.6 = /lib/i686/libm.so.6 (0x4019a000) libgcc_s.so.1 = /lib/libgcc_s.so.1 (0x401bc000) libc.so.6 = /lib/i686/libc.so.6 (0x4200) libnsl.so.1 = /lib/libnsl.so.1 (0x401c4000) /lib/ld-linux.so.2 = /lib/ld-linux.so.2 (0x8000) 1 - I know the static (.a) C++ library works because I can compile and run programs that use it. Any chance .a file was _in_ that directory. 2 - The problem XS module compiles/links without errors. Sadly -shared turns off the unresolved symbol warning.. 3 - Another XS module on the same box that use a static C++ library works OK. So try comparing the two and see if there is a difference.
Re: relocation error
Chris Masters [EMAIL PROTECTED] writes: UPDATE - It's not a perl issue. 1 - I know the static (.a) C++ library works because I can compile and run programs that use it. Any chance .a file was _in_ that directory. It was. I'll check if this works otherwise. If I move the test cpp to /tmp and try and compile, it fails. The header file is located in /usr/include. It succeeds if I move the header file into /tmp. So this isn't a perl-XS issue!! However, why would linking fail if the header is in /usr/include?? Linking has (nearly) nothing to do with the headers. Only header effect is whether names of functions are C style i.e. 'FunctionName' is just that, or C++ style where it has other characters added to encode numner and types of arguments. It is vital that the program loading the library declares the function the way it _is_ in the .so Thus if library is a C API then it MUST be declared as extern C to use from C++, but if it is C++ then it must NOT. __ Do you Yahoo!? Yahoo! Hotjobs: Enter the Signing Bonus Sweepstakes http://hotjobs.sweepstakes.yahoo.com/signingbonus
Re: XS code calling perl code, and storing stuff in an SV
Tels [EMAIL PROTECTED] writes: Now, instead of malloc() a struct like: struct BigInt { int flags; int sign; double P; double A; SV* CALC; }; and then putting a ptr to it into the PV slot, I thought I could: As I have said (at least twice recently) you can naturally do one of two things: 1. Get perl to Newz() you a struct in the PV e.g. SV *thing = newSV(sizeof(struct BigInt)); struct BigInt *p = (struct BigInt *) SvPVX(sv); I usually add: SvPOK_only(sv); SvREADONLY_on(sv); OR 2. malloc() struct and put it in the IV e.g. struct BigInt *p = (struct BigInt *) malloc(sizeof(struct BitInt)); SV *thing = newSViv(PTR2IV(p)); DO NOT malloc() and put in PV slot. Then your input and output typemaps need to match eachother.
Re: XS code calling perl code, and storing stuff in an SV
Tassilo Parseval [EMAIL PROTECTED] writes: On Mon, Jan 19, 2004 at 09:15:54AM + Nick Ing-Simmons wrote: Tels [EMAIL PROTECTED] writes: Now, instead of malloc() a struct like: struct BigInt { int flags; int sign; double P; double A; SV* CALC; }; and then putting a ptr to it into the PV slot, I thought I could: As I have said (at least twice recently) you can naturally do one of two things: 1. Get perl to Newz() you a struct in the PV e.g. SV *thing = newSV(sizeof(struct BigInt)); struct BigInt *p = (struct BigInt *) SvPVX(sv); I usually add: SvPOK_only(sv); SvREADONLY_on(sv); OR 2. malloc() struct and put it in the IV e.g. struct BigInt *p = (struct BigInt *) malloc(sizeof(struct BitInt)); SV *thing = newSViv(PTR2IV(p)); But I think the above two are the things that Tels explicitly wanted to avoid. He can avoid them sure. But he should NOT put a (system) malloc()ed thing in SvPVX() - perl is likely to Safefree() SvPVX() move it from one SV * to another on assumption is is a New() allocated char *. At first I thought this was due to size-considerations. However, storing a pointer to the BigInt structure in the IV slot will not need more memory than putting the ints into the IV and the doubles into the NV slot. IIRC an SV with _just_ an IV slot is optimized, as it one with just a PV. But when using all three slots in a clever way it has the advantage that at least the IV slot can be accessed from a Perl script, namely in numeric context. I am not against the three slots idea - by all means keep the IV bit SvIVX the NV in SvNVX and other stuff in SvPV. Or keep the other stuff in a '~' magic or ... But this is somewhat alien to the xsubpp 'typemap' concept. To use theese slots XS code needs to say its args are SV * and then cast as necessary. DO NOT malloc() and put in PV slot. Hmmh, why not? Because it will segfault on Win32 and anywhere else where perl does not use system malloc() as its allocator. Perl assumes it owns SvPVX and will free it - to perl's allocator when it is no longer required. It also assumes that it can New(xxx,foo,char,SvCUR(sv)+1); memcpy(foo,SvPVX(sv),SvCUR(sv)+1); SvPVX(sv) = malloc(42); ... When SV's REFCNT==0 perl does: Perl_Free(SvPVX(sv)) If Perl_Free != free this segfaults. Notice that on Win32 in particular perl does NOT use system malloc (or even anything remotely like it), and many platforms use perl's malloc for speed. For me, PV has never really been for strings only. It's a pointer value so storing pointers in it seems natural to me. I am not saying it has to be a string. I am saying it MUST be allocated with the allocator perl is using - malloc() is WRONG - It must be New() allocated.
Re: file-descriptor to Perl filehandle conversion
Tassilo Parseval [EMAIL PROTECTED] writes: On Mon, Jan 19, 2004 at 02:46:46AM -0800 Gisle Aas wrote: Tassilo von Parseval [EMAIL PROTECTED] writes: I was experimenting with something like PerlIO *io; char mode[8]; PerlIO_intmode2str(O_RDONLY|O_NONBLOCK, mode, NULL); io = PerlIO_fdopen(self-fd, mode); but I can't even figure out whether this works because I don't know how to turn a PerlIO* thingy into an SV. Actually, I don't know what to do with this PerlIO stuff at all. According to perlapio.pod, this is the thing to work with when doing I/O from XS. But there is not a single indication anywhere how to turn an SV into a PerlIO and vice versa. The standard perl typemap have this OUTPUT entry for PerlIO: T_INOUT { GV *gv = newGVgen($Package); if ( do_open(gv, +, 3, FALSE, 0, 0, $var) ) sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv($Package,1))); else $arg = PL_sv_undef; } Thank you, this helps. But, hmmh, unfortunately it doesn't yet solve all my problems. My first attempt: PerlIO* fh (self) CDROM *self; PREINIT: char mode[8]; PerlIO *io; CODE: { PerlIO_intmode2str(O_RDONLY|O_NONBLOCK, mode, NULL); The O_NONBLOCK _may_ be confusing it. And as thing is already open doesn't contribute much. io = PerlIO_fdopen(self-fd, mode); RETVAL = io; } OUTPUT: RETVAL This returns me something that is blessed into my class, but it is apparently not a filehandle. Looking at C code out of xsubpp would help us here. These typemaps are a little fragile - for example if you are using perl5.6 things are rather different. If the PerlIO_fdopen() has failed it isn't clear typemap will always return undef When trying to do my $fh = $cd-fh; ioctl($fh, CDROMEJECT, 0); perl will complain about $fh not being a GLOB-reference. Which would be the case for an undef - i.e. a failed fdopen(). I now do it this way and this seems to work: void fh (self) CDROM *self; PREINIT: char mode[8]; GV *gv; STLLEN modlen; CODE: { modlen = sprintf(mode, %i, self-fd); gv = newGVgen(Device::CDROM); do_openn(gv, mode, modlen, FALSE, O_RDONLY|O_NONBLOCK, 0, Nullfp, (SV**)NULL, 0); sv_setsv(ST(0), sv_2mortal(newRV((SV*)gv))); XSRETURN(1); } I am not extremely happy with this since it looks like cheating. Also I am not sure whether it is legitimate to use do_openn() since it is not in the public API (although this typemap you mentioned does something similar). The typemap uses an icky legacy interface which isn't really in the public API either. It would be good to _design_ an XS/PerlIO API - what do you want to be able to do? Anyway, even though this appears to work, I don't understand PerlIO at all. Tassilo
Re: XS code calling perl code, and storing stuff in an SV
Gisle Aas [EMAIL PROTECTED] writes: Take a look at the pictures at http://gisle.aas.no/perl/illguts/. They should explain how SVs are layed out. Thanks for the reminder - my bookmark was on the old laptop!
Re: XS code calling perl code, and storing stuff in an SV
Tels [EMAIL PROTECTED] writes: At first I thought this was due to size-considerations. However, That was the idea. I thought that a SV always has a IV, NV and PV slot, so It doesn't. See Gisle's diagrams. SV * has ONE pointer to a separately allocated something. The least memory case for an XS object is the SvPV one with a C struct hidden as binary data in the string. This saves one C level indirection in speed, and one. Bigint is: 4 (int on my system) 8 (double on my system) 4 (ptr on my system) Hmm. Probably makes sense to order that so two 4-bit things are adjacent. That makes 16 bytes. If I malloc this, it probably needs 16 bytes (malloc might padd!), and storing an PTR in the IV of the SV needs: On a 32-bit machine... The fixed part of overhead for an Object in perl is: The SV * for the reference needs 3 words. The XRV * of that reference SV needs 1 word. The SV * for the object needs 3 words. Then you have the representation cost. An SvIV costs one word for IV slot + malloced struct costs N words+sysmalloc overhead vs An SvPV costs 3 words (ptr,cur,len), + N words + perlmalloc overhead. So the PV costs two more words in the trivial case, but saves one level of indirection on access. Note that all perl's odd-sized structs are allocated in chunks. So that we get (say) 1000 1-word XRV * from perlmalloc, and then hand them out on newRV() to SVs till we run out. In another place we got say (say) 330 3-word XPVs from malloc and hand those on newPV() 38 bytes, so the malloc() strategy would actually be less (IIAC). Why is the SV bigger? CUR/LEN overhead? As soon a you print (or otherwise stringify) a numeric it goes from being a bare NV or IV to PVIV and gains a allocated string for the stringified thing. Actually, I am not sure whether Devel::Size is even correct: Perl code that gropes internals runs the risk of disturbing the state. Bit like quantum mechanics... # perl -MDevel::Peek -le '$a = 8; $b = 8; $a = 8; $a += 0.9; $b = 9; print Dump($a),Dump($b)' Anyway it really seems the malloc()/free() strategy might take less memory. Maybe (I am skeptical), but if you malloc it is in SvIV and you get an extra indirection. I have found over the last 9 years or so that puting data in PV is reasonable way to go. Tk does this for small structs, and Audio::Data does this for large arrays of 'float'. Seems to work well enough in both cases. But when using all three slots in a clever way it has the advantage that at least the IV slot can be accessed from a Perl script, namely in numeric context. But beware perl thinking it knows what it is doing in such cases. It will only use the IV slot if SvIOK is set, but if it isn't and there is an SvPOK set then it will do perl's conversion of string to IV and overwite your IV. Possibly worse if you say it has IV and it wants a string it is likely to convert IV to string and write it over the SvPV slot. I wouldn't allow this, though :) Good.
Re: file-descriptor to Perl filehandle conversion
Tassilo Parseval [EMAIL PROTECTED] writes: PerlIO *io; char mode[8]; PerlIO_intmode2str(O_RDONLY|O_NONBLOCK, mode, NULL); io = PerlIO_fdopen(self-fd, mode); PerlIO_intmode2str(O_RDONLY|O_NONBLOCK, mode, NULL); The O_NONBLOCK _may_ be confusing it. And as thing is already open doesn't contribute much. Unfortunately, the O_NONBLOCK is essential in my case as this module provides access to all the ioctls of a CDROM-drive as permitted by the kernel. Otherwise I couldn't open a drive with no CD in it. Fine - and you have opened it and got the fd. PerlIO_fdopen then takes that already open fd and associates a PerlIO * with it. PerlIO_intmde2str takes O_RDONLY and turns it into stdio-like r. Stdio and PerlIO have no way to represent O_NONBLOCK so (having now looked) it just ignores it. I was just trying to reproduce the result of using the typemap. What was returned was not undef according to Devel::Peek. The funny thing now is: The above, which didn't work this morning, now works! I am seriously confused. Any chance some other process had the CDROM in use this morning? It'd be nice having a bridge between Perl filehandles (that is, references to globs) and C handles (both file-descriptors and FILE*). Often C libraries work on filehandles but exposing those to pure Perl as glob-references is tricky. In particular, I wish we had PerlIO *PerlIO_importfd(int fd, int mode); You do have: PerlIO *PerlIO_fdopen(int fd, const char *); What seems to be troubling us is getting a glob ref from one of those so what we want is SV *PerlIO_perlhandle(PerlIO *f); Going the other way (XSUB gets a glob-ref and needs FILE*/fd) isn't always smooth either. First step is to get the IO * Perl_sv2io() does that. Next you get your PerlIO * - you have a choice of two the one for output and the one for input (often same but not for sockets or (some) ttys). Getting a FILE * isn't smooth, but we have an API for that. Getting a fd is just PerlIO_fileno(PerlIO *f) For that purpose, I made two macros: #ifdef _WIN32 # define PerlIO_exportFILE(f,fl) ((FILE*)(f)) #endif Especially the _WIN32 branch is fishy. But it was on this list that someone said that on windows a PerlIO* would just be an alias for FILE*. It was on perl5.6 - not on perl5.8. #define sv_to_file(sv) (PerlIO_exportFILE(IoIFP(sv_2io(sv)), NULL)) That is okay anywhere with perl5.8+ - but please read the PODs. In perl5.8+ there isn't necessarily a FILE * in normal perl IO. So the above may have to FILE *stdio = fdopen(PerlIO_fileno(pio),mode)) and how the FILE *stdio and PerlIO *pio interact is messy.
Re: XS code calling perl code, and storing stuff in an SV
Tassilo Parseval [EMAIL PROTECTED] writes: For me, PV has never really been for strings only. It's a pointer value so storing pointers in it seems natural to me. I am not saying it has to be a string. I am saying it MUST be allocated with the allocator perl is using - malloc() is WRONG - It must be New() allocated. With New, you mean the macro New(), I hope (as opposed to usemymalloc). Yes I mean New() macro. In this case I am relatively relieved since I adopted the habit of always using New/Safefree. So I should be on the safe side (knocking on wood). Tassilo
Re: file-descriptor to Perl filehandle conversion
Tassilo Parseval [EMAIL PROTECTED] writes: My concern was with PerIO_fdopen(). I didn't know whether perl would reuse the fd (and simply sort of wrap it in a PerlIO) or duplicate it. There is a pod which tells you. In case of duping, ignoring O_NONBLOCK would be bad. AFAIK a dup()ed fd inherits the non-blocking-ness along with all the other kernel level attributes like file position. The problem with fd-versus-FILE IO is eventually what bothers me. For Perl5.8+ you can avoid the buffering issues of that problem by just using :unix layer. Going the other way (XSUB gets a glob-ref and needs FILE*/fd) isn't always smooth either. First step is to get the IO * Perl_sv2io() does that. Next you get your PerlIO * - you have a choice of two the one for output and the one for input (often same but not for sockets or (some) ttys). Getting a FILE * isn't smooth, but we have an API for that. Getting a fd is just PerlIO_fileno(PerlIO *f) That reads amazingly simple as you describe it. Good that I can from now on look it up for future reference. For that purpose, I made two macros: #ifdef _WIN32 # define PerlIO_exportFILE(f,fl) ((FILE*)(f)) #endif Especially the _WIN32 branch is fishy. But it was on this list that someone said that on windows a PerlIO* would just be an alias for FILE*. It was on perl5.6 - not on perl5.8. Bah! That means I have to change one of my modules. Quite unsurprisingly, the branch of the code that converted a glob-ref to a FILE* was not covered by the tests. :-( #define sv_to_file(sv) (PerlIO_exportFILE(IoIFP(sv_2io(sv)), NULL)) That is okay anywhere with perl5.8+ - but please read the PODs. In perl5.8+ there isn't necessarily a FILE * in normal perl IO. So the above may have to FILE *stdio = fdopen(PerlIO_fileno(pio),mode)) Sigh, so not even my non-Win32 path is necessarily right. Why do you need a FILE *? Won't a PerlIO * do? - you always have one of those. IMHO you only need a FILE * for passing external C libraries that expect such a thing. Anyway, Nick, thanks for your patient attempts to explain this book with 7^7 seals to me. I think I'm now able to find a way through this muddle somehow. I will try and remember to add the essence of these discussions to the PODs.
Re: file-descriptor to Perl filehandle conversion
Tassilo Parseval [EMAIL PROTECTED] writes: AFAIK a dup()ed fd inherits the non-blocking-ness along with all the other kernel level attributes like file position. As I've read in the PODs now, PerlIO_fdopen() will not dup the handle (since fdopen wont do it) and so I can't use it. As you have descended to this OS level layer anyway what is wrong with calling PerlLIO_dup() yourself? I am assuming that dup is essential to avoid double-close issues? What else is going to close it? Can that close be supressed leaving perl to do the close()? perlapio.pod mentions dup only once (in PerlIO_reopen) and that doesn't help: Perl prefers to dup the new low-level descriptor to the descrip- tor used by the existing PerlIO. This may become the behaviour of this function in the future. PerlIO is trying to hide numeric fd level as a POSIX specific OS feature. Win32 IO could be a lot more efficient if we could get perl to loose its numeric fd fixation. On Win32 IO has a Handle which is a pointer-sized thing and values are non-consecutive. I've come to the conclusion that I will use the $fd trick and use do_openn() because thus I can pass 'Nullfp' as the PerlIO* argument. Fine. The only reason I can see for not adding do_openn() to public API is its interface is insanely complex and flexible. The problem with fd-versus-FILE IO is eventually what bothers me. For Perl5.8+ you can avoid the buffering issues of that problem by just using :unix layer. This is good to know. I haven't yet looked much into the layers stuff though. #define sv_to_file(sv) (PerlIO_exportFILE(IoIFP(sv_2io(sv)), NULL)) That is okay anywhere with perl5.8+ - but please read the PODs. In perl5.8+ there isn't necessarily a FILE * in normal perl IO. So the above may have to FILE *stdio = fdopen(PerlIO_fileno(pio),mode)) Sigh, so not even my non-Win32 path is necessarily right. Why do you need a FILE *? Won't a PerlIO * do? - you always have one of those. IMHO you only need a FILE * for passing external C libraries that expect such a thing. This was my situation. The library was able to deal with either a filename or a FILE* handle. It was therefore natural to allow the same thing from Perl. Fine. That sort of library a pain - even using it from C++ with iostreams isn't clean :-(
Re: file-descriptor to Perl filehandle conversion
Tassilo Parseval [EMAIL PROTECTED] writes: On Wed, Jan 21, 2004 at 09:20:40AM + Nick Ing-Simmons wrote: Tassilo Parseval [EMAIL PROTECTED] writes: AFAIK a dup()ed fd inherits the non-blocking-ness along with all the other kernel level attributes like file position. As I've read in the PODs now, PerlIO_fdopen() will not dup the handle (since fdopen wont do it) and so I can't use it. As you have descended to this OS level layer anyway what is wrong with calling PerlLIO_dup() yourself? Ah, there is a dup() and dup2() macro in XSUB.h. I missed it because it isn't mentioned in any of the PODs. PerlLIO_dup() form is what you should call though - if you might ever care about Win32. I am assuming that dup is essential to avoid double-close issues? What else is going to close it? Can that close be supressed leaving perl to do the close()? It could. I would just need to bless the returned GLOB-ref into a class of my own and define a close() and DESTROY() method for it (both will do nothing). There is even a way to avoid exporting a Perl handle at all, I just realized. I just do it because my module doesn't handle all ioctls (I have no DVD-drive so I don't implement those as I couldn't test them). But instead of letting the user do ioctl($cdrom-fh, DVD_READ_STRUCT, $packed_string); I could change the interface to $cdrom-ioctl(DVD_READ_STRUCT, $packed_string); That sounds like an excellent idea. and inside ioctl(): ioctl(self, op, data) CROM *self; int op; SV* data; CODE: ... ioctl(self-fd, op, SvPVX(data)); /* after the appropriate checks of 'data' */ ... Thus I could avoid any perlio issues. Fine. The only reason I can see for not adding do_openn() to public API is its interface is insanely complex and flexible. A few macros could be built on top of it, like: gvref_from_fd(fd,sv) { \ char mode[8]; \ STRLEN len = sprintf(mode, %i, (fd)); \ GV *gv = newGVgen(main); \ do_openn(gv, mode, len, FALSE, mode, 0, Nullfp, (SV**)NULL, 0); \ sv_setsv((sv), sv_2mortal(newRV((SV*)gv))); \ } Hmm ... need to think about that, but defining a few obvious ones as the public API might be safer than trying to explain all the paths through do_openn(). As I understand the perl source, do_openn() is almost almighty and is used for everything open-related in Perl. Yes.
Re: complex compile line into Makefile.PL
Chris Masters [EMAIL PROTECTED] writes: Hi All, I'm having trouble fitting the following compile line into my Makefile.PL: gcc -pipe -DNDEBUG -w -O3 -L/usr/local/BerkeleyDB.4.1/lib/ -lstlport_gcc -ldb_cxx -luuid -lpthread -lcurl -lc -lstdc++ -lz -w -pthread -fexceptions -D_GNU_SOURCE -D_MBCS -DCbUNIX -DCbLINUX -DLOW_TIMERESOLUTION -fvtable-thunks -D__i486__ -DTHREAD_SAFE -D_REENTRANT -Wl,-rpath,.:..:/usr/local/BerkeleyDB.4.1/lib/:/usr/lib:/lib:/usr/local/lib mytestcode.c -o mytestcode -lmylib -lxml2 I've attempted using: 'LIBS' = ['-L/usr/local/BerkeleyDB.4.1/lib/ -pthread -fexceptions -lmylib-lxml2 -lstlport_gcc -ldb_cxx -luuid -lpthread -lcurl -lc -lstdc++ -lz -w'] 'DEFINE'= '-D_GNU_SOURCE -D_MBCS -DCbUNIX -DCbLINUX -DLOW_TIMERESOLUTION -fvtable-thunks -D__i486__ -DTHREAD_SAFE -D_REENTRANT -Wl,-rpath,.:..:/usr/local/BerkeleyDB.4.1/lib/:/usr/lib:/lib:/usr/local/lib' perl Makefile.PL gives: [EMAIL PROTECTED] my_url_perl]$ perl Makefile.PL Checking if your kit is complete... Looks good Unrecognized argument in LIBS ignored: '-pthread' Unrecognized argument in LIBS ignored: '-fexceptions' Note (probably harmless): No library found for -ldb_cxx Unrecognized argument in LIBS ignored: '-w' Writing Makefile for cobion_URL_Perl [EMAIL PROTECTED] my_url_perl]$ Is there a good guide to fitting compile lines into Makefile.PL? You need to split the compile lines into two parts: the parts that go to the compiler and the parts that go to the linker. Given your: gcc -pipe -DNDEBUG -w -O3 -L/usr/local/BerkeleyDB.4.1/lib/ -lstlport_gcc -ldb_cxx -luuid -lpthread -lcurl -lc -lstdc++ -lz -w -pthread -fexceptions -D_GNU_SOURCE -D_MBCS -DCbUNIX -DCbLINUX -DLOW_TIMERESOLUTION -fvtable-thunks -D__i486__ -DTHREAD_SAFE -D_REENTRANT -Wl,-rpath,.:..:/usr/local/BerkeleyDB.4.1/lib/:/usr/lib:/lib:/usr/local/lib mytestcode.c -o mytestcode -lmylib -lxml2 You should be aware that that is probably not doing what you think it is doing - in particular the -l lines that occur before the source file are likely ignored. The -rpath part is also a little risky and is going to be a pain to get through. I am not sure what implications of compiling for -fexceptions and -fvtable-thunks will have on code to be linked to perl. I suspect it means you need to use g++ to link it... The -D options have potential to collide with ones perl needs to use. I suspect the -pipe and -O3 should go ... I think you want something like (line wrapped...) # compile options chucked in DEFINE DEFINE = [-pipe -O3 -DNDEBUG -pthread -w -fexceptions -D_GNU_SOURCE -D_MBCS -DCbUNIX -DCbLINUX -DLOW_TIMERESOLUTION -fvtable-thunks -D__i486__ -DTHREAD_SAFE -D_REENTRANT], # LINK options in LIBS LIBS = [-L. -L.. -L/usr/local/BerkeleyDB.4.1/lib/ -L/usr/local/lib -lmylib -lxml2 -lstlport_gcc -ldb_cxx -luuid -lpthread -lcurl lstdc++ -lz -lc ], Goal of extra -Ls are to try an replicate the -rpath stuff without being explicit. It relies of MakeMaker setting LD_RUN_PATH to -Ls that get used, and LD_RUN_PATH being equivalent to -rpath. If that doesn't work you may have to get LD defined in Makefile as (say): LD = g++ -Wl,-rpath,.:..:/usr/local/BerkeleyDB.4.1/lib/:/usr/lib:/lib:/usr/local/lib
Re: Help define XS functionality for Module::Build
Randy W. Sims [EMAIL PROTECTED] writes: I'm also trying to figure out how best to implement nested builds. What degree of auto scanning for files should be used if any? Suggest we start small. If we have a non-auto scheme then us clever nested module authors can write our own scans. Risk with that is we get a lot of incompatible schemes. Doing nested builds is probably one of the biggest features currently missing from Module::Build. It's probably the feature that needs to be added next as it may influence other things. I'm trying to come up with some use cases, but you may be the best qualified to help work out some of the issues. The issues I'm currently thinking about are the relationships and communcation paths between each sub-build. What information is fed from the top level to lower levels? I think this should be just a special case of parent/child. If parent wants child to see grandad's info it can pass it on. What information is fed from parent to child? Unclear. MakeMaker had a habit of passing on too much. In particular passing on relative -I flags which didn't work, and making them override ones child had figured out for itself. Tk's scheme is have each Makefile.PL call Tk::MMutil (which gets required by top level so there are no @INC issues). But it has all got overly complex. I'm not sure it would be a good idea to allow sibling builds to communicate directly, because it adds too much complexity, Agreed. but client/server where the top 'Build.PL' is the server seems a safer design. This is less clear. The toplevel might know little about its great-grandchildren. That said this is net effect of my Tk::MMutil scheme. Is communication strictly downward (like make) or bi-directional? I think downward is okay. One issue Tk has though is with the ordering of builds. Most sub-dirs are best built after parent. But one builds the library (MYEXTLIB) used by the top level and the others and has to be built first. When we run './Build.PL', should we scan recursively, Depends what you mean. I don't think toplevel should `find . -name 'Build.PL` but glob(*/Build.PL) is probably okay. Both Tk and Audio have sub-sub extensions which get conditionaly built based on what sub-extension discovers. Latest Tk now has 'Makefile.maybe' in a couple of spots so that (for example) Tk::PNG looks for -lpng and -lz already existing on the system and uses them. Otherwise it copies libpng/Makefile.maybe to libpng/Makefile.PL and then MakeMaker builds libpng. invoking each 'Build.Pl' we run into? Or, should the author specify explicitly which 'Build.Pl' gets invoked and in what order. Probably both. Sorry to probe your brain, but I want to get this right before I start coding it. I'm more inclined to think that, for compiled code, everything should be specified explicitly instead of doing a directory scan and compiling every file in sight. You certainly need a mechanism to prune it. Complex extensions often have a configure step of their own and may have a Foo.c which is only to be used if foo is available. Tk has a number of these and MM's compile-all approach means several have #ifdef HAVE_FOO ... #endif wrapped round the entire file body! (Files with no content upset some systems though so one stub is usually left.) In other cases Tk's Makefile.PLs reach into the MM struct in a post_initialize method and remove files from the list(s). Ick. Maybe I need to spend some time studying Tk's Makefile.PL's to see how we can make this cleaner... By all means look - it isn't pretty and I am not proud of it. Thanks, Randy.
Re: Leakage in XS replacement for UNIVERSAL::VERSION
John Peacock [EMAIL PROTECTED] writes: upg_version() creates a temporary string copy (Safefree()'d) of the incoming SV and then calls scan_version(), which in turn does this (where rv is the incoming SV which will ultimately be returned to the top level caller): SV* sv = newSVrv(rv, version); /* create an SV and upgrade the RV */ (void)sv_upgrade(sv, SVt_PVAV); /* needs to be an AV type */ That makes no sense to me at all. You create a new RV with a reference to the incoming (mortal) SV. Making that refrence incrementents the REFCOUNT of the incoming mortal. You then clobber that reference SV and turn it into an AV. What you would normaly do is AV *av = newAV(); ... rv = newRV_noinc((SV *) av); return rv; But you have made things difficult for yourself by passing in an SV The easy way to do it is: AV *av = newAV(); SV *temp = newRV_noinc((SV *) av); sv_setsv(rv, temp); SvREFCNT_dec(temp); But your version of my temp is the nsv in caller. You can avoid the create/destroy by doing lower level stuff: sv_upgrade(rv, SVt_RV); SvRV(rv) = (SV *) av; ...no allocation of memory here... /* Append revision */ av_push((AV *)sv, newSViv(rev)); After this code has run, the rv contains a reference to an AV, containing 2 or more IV elements. Everything has only 1 reference up the line. The top level code (in UNIVERSAL_VERSION) has done this: SV *nsv = sv_newmortal(); sv_setsv(nsv, sv); sv = nsv; if ( !sv_derived_from(sv, version)) upg_version(sv); If I was doing this I would have done something like: if ( !sv_derived_from(sv, version)) { SV *nsv = upg_version(sv); sv_setsv(sv,nsv); SvREFCNT_dec(nsv); } p.s. rather than attaching the source code here; the current version module can be retrieved from CPAN Not trivially in my case.
Re: PerlIO_seek() changed in 5.8.1+?
Dan Sully [EMAIL PROTECTED] writes: * Nick Ing-Simmons [EMAIL PROTECTED] shaped the electrons to say... I have seen weird fails like this when varying large file support and 64/32 bit IV Configure options. What happens is that 'offset' (your variable) is wrong size for Off_t and PerlIO_seek mis-interprets what it gets in its incoming args. You seem to have a small-file 32-bit perl (from -V output below). That is correct. And yes, the 'offset' is really a 'ogg_int64_t'. Although it's certainly not a 64bit value. 'ogg' ?? How big is it. I've tried casting it to a Off_t to no effect. Hmm, perhaps Off_t itself is off. Did you pass same -D flags to your compile as perl build? For 32-bit build perl uses off_t as Off_t - which is all very well but Linux at least varies size of off_t based on -D options of _your_ compile. So if your command line or one of headers included by your XS code defines (say) __USE_FILE_OFFSET64 things get confused. Suggestions here? Add some diagnostics to XS code e.g. warn(Passing offset size=%d Off_t=%d,sizeof(offset),sizeof(Off_t)); Can I/we see: A. Your declaration of offset B. Typedef(s) of types involved from any system/library .h files? C. CPP-ed code of call to PerlIO_seek(). You can get (C) by make Foo.i where you have a Foo.xs This is something that needs to really work on at the very least Linux/*BSD, Win32 OSX. thanks. -D
Re: T_PTROBJ and NULL Pointers
Bill Hails [EMAIL PROTECTED] writes: Hi, hopefully this is pretty straightforward. I'm using perl v5.6.1 and building an XS wrapper around FreeBSD's kevent/kqueue functions. The library passes around poiunters to structures, which I'm blessing into a package using the T_PTROBJ typemap entry. This works fine if the pointers are non-null, but if I return a null pointer, it seems like the blessing fails. The code is pretty simple: /* Kqueue.xs */ typedef struct kevent *_Kevent; ... MODULE = Kqueue PACKAGE = _Kevent ... _Kevent create(size=1) u_int size CODE: if (size 0) { RETVAL = (_Kevent) calloc(size, sizeof(struct kevent)); } else { RETVAL = (_Kevent) 0; } OUTPUT: RETVAL ... MODULE = Kqueue PACKAGE = Kqueue int _kevent(kq, changelist, nchanges, eventlist, nevents, timeout = NULL) Kqueue kq _Kevent changelist int nchanges _Kevent eventlist int nevents Timeout timeout INIT: /* typemap */ _Kevent T_PTROBJ The call to Kqueue::_kevent() fails with: Use of uninitialized value in subroutine entry at blib/lib/Kqueue.pm line 228. eventlist is not of type _Kevent at blib/lib/Kqueue.pm line 228. Where eventlist is what _Kevent::create(0) returned, i.e. a blessed reference to a null pointer. On inspection of the C output, this reduces to ST(0) = sv_newmortal(); sv_setref_pv(ST(0), _Kevent, (void*)0); Does sv_setref_pv assume undef if its 3rd arg is null? I believe it does. I quite like that, but it is a save that the T_PTROBJ INPUT side doesn't accept undef as NULL to match.
Re: Controlling warnings and strict during runtime
Tassilo Parseval [EMAIL PROTECTED] writes: On Mon, Jan 26, 2004 at 04:28:23PM -0800 unkno me wrote: As for warnings, I had this problem recently. I have defined two macros: #define WARN_OFF \ SV *oldwarn = PL_curcop-cop_warnings; \ PL_curcop-cop_warnings = pWARN_NONE; #define WARN_RESTORE \ PL_curcop-cop_warnings = oldwarn; WARN_RESTORE has to be called in the same scope of WARN_OFF, or you make 'oldwarn' a global variable. Nick Ing-Simmons mentioned that one could use save_item() to save the old value of PL_curcop-cop_warnings scope-wise. That however didn't work for me and resulted in segfaults. The SAVE stuff in scope.h can probably be used, but I am not entirely surprised save_item() doesn't work. The various save_xxx functions/macros have expectations on the things being saved and the scope structure. Tassilo
Re: Unfortunate question about compiling embedded application on Perl 5.8.1 ...
Stanley Hopcroft [EMAIL PROTECTED] writes: Dear Folks, I am writing to thank you for encouragement and help this list has been to me, and to ask for your comments on this situation. A small application (call it a copy) based on the persistent.c example from perlembed was working quite happily (modulo threaded Perls) for Perl 5.005_03, 5.6.1 and 5.8.0. On 5.8.1 however, it will not compile, reporting [EMAIL PROTECTED] contrib]$ make mini_epn perl -MExtUtils::Embed -e xsinit gcc -g -O2 -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -I/usr/lib/perl5/5.8.1/i386-linux-thread-multi/CORE -DHAVE_CONFIG_H -c perlxsi.c `perl -MExtUtils::Embed -e ccopts` gcc -g -O2 -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -I/usr/lib/perl5/5.8.1/i386-linux-thread-multi/CORE -DHAVE_CONFIG_H -c mini_epn.c `perl -MExtUtils::Embed -e ccopts` mini_epn.c: In function `main': mini_epn.c:116: error: `my_perl' undeclared (first use in this function) mini_epn.c:116: error: (Each undeclared identifier is reported only once mini_epn.c:116: error: for each function it appears in.) make: *** [mini_epn] Error 1 The difference between code that compiles (and runs) on the 5.8.1 system is _only_ the name of the Perl interpreter variable, Which as you have discovered is important. If your perl is configured for threads or multiplicity (and yours is both) there must be a PerlInterpreter *my_perl in scope before you call almost any of perl's internals. Which line is 116 ? And can we see perl -V output for the perl you used there.
Re: Are perl_parse and perl_run thread safe?
Aditya Prasad [EMAIL PROTECTED] writes: Hello, I wanted to know if the functions perl_parse and perl_run are thread safe. In other words, i am using multiple perl interpreters allocated in different threads and these threads will be running parallely. I noticed that when one of the threads was paused using the Thread Pause function and if it was in perl_parse / perl_run / perl_destruct the other thread would get stuck when encountering one of the perl_parse / perl_run / perl_destruct functions. I am embedding the multiple perl interpreters in a multithreaded process in Windows 2000/XP. Please advise me if i need to protect these functions. This may be better on the main p5p list (CC:ed) AFAIK you have to have one perl interpreter per-thread. thanks and regards, aditya Confidentiality Notice The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain confidential or privileged information. If you are not the intended recipient, please notify the sender at Wipro or [EMAIL PROTECTED] immediately and destroy all copies of this message and any attachments. This is a mailing list with open supscription - you should not be sending confidential stuff here ;-)
Re: Odd T_PTROBJ behaviour
Simon Wistow [EMAIL PROTECTED] writes: On Thu, Feb 19, 2004 at 05:53:24PM -0500, Randy W. Sims said: I'm just catching up on some of the mailing lists, and it looks like no ones answered your question, so... Much appreciated. Unfortunatelly, there is little up-to-date documentation on mixing C++ with XS (at least that I know about) although it is pretty well supported. The best that I know of is a very brief section in Extending and Embedding Perl http://www.manning.com/jenness I ended up prodding Simon Coznes and then getting the book and some general good old fashioned beating it to death until I managed to get it all working. I ended using a typemap like TYPEMAP Reelmaker * O_OBJECT float T_NV OUTPUT # The Perl object is blessed into 'CLASS', which should be a # char* having the name of the package for the blessing. O_OBJECT sv_setref_pv( $arg, CLASS, (void*)$var ); INPUT O_OBJECT if( sv_isobject($arg) (SvTYPE(SvRV($arg)) == SVt_PVMG) ) $var = ($type)SvIV((SV*)SvRV( $arg )); else{ warn( \${Package}::$func_name() -- $var is not a blessed SV reference\ ); XSRETURN_UNDEF; } and after that adding all the functions was laughably simple to the point where I'm thinking of just writign a script that will rampage though and generate the XS for me. I have one which I must try and shake loose from day job. It runs g++ -E and though output for C++ public API of class(es) and builds a perl shadow class heirachy that matches the C++ public API. I'd be happy to write up some faqs or a Perl.com article on what I did, especially since I was simultaneously wrapping the same library in Python and Lua. Mine does perl and has beginings of Java. FWIW I was also used Module::Build rather and ExtUtils::MakeMaker Well worth an article then! Simon