Tassilo von Parseval wrote:

On Fri, Oct 31, 2003 at 12:39:14PM +1100 Sisyphus wrote:


Steve Hay wrote:



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



I get a segfault, which is what I would expect. You only allocate memory
for the string but not for the SV to be returned.
[snip]


One could change it to:

SV *
hello()
PREINIT:
char *chartext;
SV *svtext;
CODE:
Newz(0, chartext, 13, char);
svtext = newSV(0);
strcpy(chartext, "Hello, world");
sv_usepvn(svtext, chartext, strlen(chartext));
RETVAL = svtext;
OUTPUT:
RETVAL


Cool - thanks for the explanation. I've simplified the above slightly to use RETVAL itself as the SV *:

   SV *
   hello()
       PREINIT:
           char    *chartext;

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

       OUTPUT:
           RETVAL

This still works fine.

That contrasts interestingly with the void xsub case:

   void
   hello()
       PREINIT:
           char    *chartext;

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

which works without having to say "ST(0) = newSV(0)". Does that mean that ST(0) is already an allocated SV *?

If so, is that always the case? In a previous thread discussing returning lists from xsubs (http://www.perldiscuss.com/article.php?id=1112&group=perl.xs) it was pointed out that when using EXTEND / PUSHs you get one free push if the xsub was called from Perl, but don't if it was called from another xsub. What I'm wondering is would ST(0) still be a preallocated SV * if the xsub was called from another xsub?

(I would try it out to see, but I don't know how to call an xsub from another xsub! How does one do that?)

- Steve



Reply via email to