Re: Manipulating the perl stack from within a non-XSUB function

2000-05-16 Thread Nick Ing-Simmons

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

2000-05-14 Thread Nick Ing-Simmons

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

2000-11-07 Thread Nick Ing-Simmons

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

2000-12-21 Thread Nick Ing-Simmons

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*

2001-01-29 Thread Nick Ing-Simmons

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?

2001-07-13 Thread Nick Ing-Simmons

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?

2001-11-30 Thread Nick Ing-Simmons

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?

2001-12-01 Thread Nick Ing-Simmons

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

2001-12-21 Thread Nick Ing-Simmons

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

2002-01-31 Thread Nick Ing-Simmons

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

2002-03-25 Thread Nick Ing-Simmons

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

2002-04-17 Thread Nick Ing-Simmons

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

2002-05-20 Thread Nick Ing-Simmons

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

2002-05-21 Thread Nick Ing-Simmons

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

2002-05-23 Thread Nick Ing-Simmons

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

2002-06-14 Thread Nick Ing-Simmons

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

2002-09-24 Thread Nick Ing-Simmons

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

2002-09-29 Thread Nick Ing-Simmons

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

2002-10-13 Thread Nick Ing-Simmons

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

2002-10-13 Thread Nick Ing-Simmons

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

2002-10-23 Thread Nick Ing-Simmons
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

2002-10-25 Thread Nick Ing-Simmons
,
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

2002-11-17 Thread Nick Ing-Simmons
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

2002-12-06 Thread Nick Ing-Simmons
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

2003-01-14 Thread Nick Ing-Simmons
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

2003-01-17 Thread Nick Ing-Simmons
: 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

2003-01-19 Thread Nick Ing-Simmons
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

2003-01-21 Thread Nick Ing-Simmons
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

2003-01-26 Thread Nick Ing-Simmons
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

2003-02-06 Thread Nick Ing-Simmons
[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

2003-03-05 Thread Nick Ing-Simmons
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

2003-03-11 Thread Nick Ing-Simmons
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

2003-03-11 Thread Nick Ing-Simmons
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

2003-03-17 Thread Nick Ing-Simmons
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

2003-03-23 Thread Nick Ing-Simmons
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???

2003-04-02 Thread Nick Ing-Simmons
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.

2003-06-06 Thread Nick Ing-Simmons
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)

2003-06-06 Thread Nick Ing-Simmons
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

2003-06-01 Thread Nick Ing-Simmons
) $(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

2003-06-03 Thread Nick Ing-Simmons
[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

2003-06-04 Thread Nick Ing-Simmons
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

2003-06-16 Thread Nick Ing-Simmons
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.

2003-07-24 Thread Nick Ing-Simmons
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

2003-07-25 Thread Nick Ing-Simmons
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()?

2003-08-10 Thread Nick Ing-Simmons
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

2003-08-14 Thread Nick Ing-Simmons
[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

2003-08-14 Thread Nick Ing-Simmons
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

2003-08-14 Thread Nick Ing-Simmons
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

2003-08-21 Thread Nick Ing-Simmons
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

2003-08-21 Thread Nick Ing-Simmons
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

2003-08-21 Thread Nick Ing-Simmons
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

2003-08-28 Thread Nick Ing-Simmons
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

2003-09-07 Thread Nick Ing-Simmons
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

2003-09-08 Thread Nick Ing-Simmons
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

2003-09-17 Thread Nick Ing-Simmons
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

2003-09-17 Thread Nick Ing-Simmons
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

2003-09-18 Thread Nick Ing-Simmons
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?

2003-09-18 Thread Nick Ing-Simmons
[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]

2003-09-18 Thread Nick Ing-Simmons
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

2003-09-22 Thread Nick Ing-Simmons
[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

2003-09-23 Thread Nick Ing-Simmons
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

2003-10-04 Thread Nick Ing-Simmons
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

2003-10-30 Thread Nick Ing-Simmons
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

2003-10-30 Thread Nick Ing-Simmons
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

2003-10-30 Thread Nick Ing-Simmons
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

2003-10-30 Thread Nick Ing-Simmons
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

2003-10-30 Thread Nick Ing-Simmons
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

2003-10-31 Thread Nick Ing-Simmons
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

2003-10-31 Thread Nick Ing-Simmons
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

2003-11-17 Thread Nick Ing-Simmons
[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

2003-11-26 Thread Nick Ing-Simmons
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

2003-12-09 Thread Nick Ing-Simmons

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

2003-12-10 Thread Nick Ing-Simmons
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

2003-12-23 Thread Nick Ing-Simmons
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..

2004-01-06 Thread Nick Ing-Simmons
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

2004-01-10 Thread Nick Ing-Simmons
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

2004-01-10 Thread Nick Ing-Simmons
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

2004-01-10 Thread Nick Ing-Simmons
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

2004-01-11 Thread Nick Ing-Simmons
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

2004-01-14 Thread Nick Ing-Simmons
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

2004-01-17 Thread Nick Ing-Simmons
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

2004-01-19 Thread Nick Ing-Simmons
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

2004-01-19 Thread Nick Ing-Simmons
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

2004-01-19 Thread Nick Ing-Simmons
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

2004-01-19 Thread Nick Ing-Simmons
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

2004-01-19 Thread Nick Ing-Simmons
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

2004-01-19 Thread Nick Ing-Simmons
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

2004-01-20 Thread Nick Ing-Simmons
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

2004-01-20 Thread Nick Ing-Simmons
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

2004-01-21 Thread Nick Ing-Simmons
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

2004-01-21 Thread Nick Ing-Simmons
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

2004-01-21 Thread Nick Ing-Simmons
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

2004-01-23 Thread Nick Ing-Simmons
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

2004-01-23 Thread Nick Ing-Simmons
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+?

2004-01-26 Thread Nick Ing-Simmons
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

2004-01-29 Thread Nick Ing-Simmons
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

2004-01-29 Thread Nick Ing-Simmons
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 ...

2004-02-10 Thread Nick Ing-Simmons
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?

2004-02-08 Thread Nick Ing-Simmons
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

2004-02-20 Thread Nick Ing-Simmons
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



  1   2   3   >