Nick Ing-Simmons wrote:

Sisyphus <[EMAIL PROTECTED]> writes:



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.


It looks like either the void xsub or the SV * xsub is the way to go, rather than a char * one, and the use of sv_usepvn() has been recommended twice (if space is being allocated elsewhere).

So I tried rewriting my original example like this:

SV *
hello()
   PREINIT:
       char    *chartext;
       SV    *svtext;

   CODE:
       Newz(0, chartext, 13, char);
       strcpy(chartext, "Hello, world");
       sv_usepvn(svtext, chartext, 13);
       RETVAL = svtext;

   OUTPUT:
       RETVAL

However, I now find that when I call that from Perl ($greeting = Foo::hello()) then I get this error:

Modification of a read-only value attempted

Why does that happen?

I also tried avoiding the need for the extra SV * like this:

SV *
hello()
   PREINIT:
       char    *chartext;

   CODE:
       Newz(0, chartext, 13, char);
       strcpy(chartext, "Hello, world");
       sv_usepvn(RETVAL, chartext, 13);

   OUTPUT:
       RETVAL

I assume that's OK to do, except that it still has the same problem!

Both of these versions also produce a compiler warning that the SV * (svtext in the first example, RETVAL in the second) is "used without having been initialised". What should I initialise it to?

I had more success with the void xsub style:

void
hello()
   PREINIT:
       char    *chartext;

   CODE:
       Newz(0, chartext, 13, char);
       strcpy(chartext, "Hello, world");
       sv_usepvn(ST(0), chartext, 13);
       XSRETURN(1);

That works fine - no errors, no warnings, no leaks - but I'd still like to understand where I've gone wrong with the SV * style xsub above.

Thanks for all the advice so far.
- Steve



Reply via email to