Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

SV creation inside XS

by llancet (Friar)
on Nov 06, 2011 at 15:22 UTC ( [id://936297]=perlquestion: print w/replies, xml ) Need Help??

llancet has asked for the wisdom of the Perl Monks concerning the following question:

Hi, everyone!

I'm trying to make some wrapper, but found something that I don't really understand. This is the test code:

This is the XS part
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" MODULE = xstest PACKAGE = xstest SV* new() CODE: HV* hv = newHV(); RETVAL = newSVrv((SV*)hv, NULL); OUTPUT: RETVAL
This is the perl part:

#!/usr/bin/perl use common::sense; use xstest; my $obj = xstest::new(); say "object is: $obj";

I expect to have a hashref returned, but instead I got nothing. Why?

Replies are listed 'Best First'.
Re: SV creation inside XS
by BrowserUk (Patriarch) on Nov 06, 2011 at 17:30 UTC

    You're making the same mistake I (and others) made. That of assuming that newSVrv() creates a new RV that points to the SV passed to it as an argument. It doesn't.

    The documentation for the call reads:

    newSVrv

    Creates a new SV for the RV, rv, to point to. If rv is not an RV then it will be upgraded to one. If classname is non-null then the new SV will be blessed in the specified package. The new SV is returned and its reference count is 1.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Got it!
      But what should I do if I want to bless an exist HV to some package? For instance, if the HV is from somewhere else, and I want to bless it into xstest package...

        Search perlapi for sv_bless()

        sv_bless

        Blesses an SV into a specified package. The SV must be an RV. The package must be designated by its stash (see gv_stashpv() ). The reference count of the SV is unaffected.

        SV* sv_bless(SV* sv, HV* stash)

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: SV creation inside XS
by dave_the_m (Monsignor) on Nov 06, 2011 at 17:13 UTC
    I expect to have a hashref returned, but instead I got nothing. Why?
    Because newSVrv() doesn't do what you think it does. It converts its arg into an RV and makes it point to a new, null SV that it creates, and returns.

    You probably want newRV_noinc() instead.

    Dave.

Re: SV creation inside XS
by patcat88 (Deacon) on Nov 07, 2011 at 01:45 UTC
    HV* hv = newHV(); RETVAL = newSVrv((SV*)hv, NULL);
    As said before, newSVrv is wrong. Make sure you use newRV_noinc since newHV has a ref count of 1 already. If you bring HV to 2 and return the RV to Perl land, the HV is now memory leaked because when the RV is garbage collected, the HV will stay forever. HV and AVs must be returned in RVs to Perl land. If you try to return a HV or AV without it being in an RV, you will get the "bizarre copy" die the next time a perl op sees it. Remember, RETVALed or OUTPUTed SV* get mortalized behind the scenes (look at your .c file), so they should be left by you with refcount 1, and NOT mortalized. As I recall, perl gets very noisy (can't remember if it is a warning or fatal) if your double mortaled SV * or derivative appears. perl will try to delete the SV twice. perl will catch the double mortaled SV because perl will be freeing something already freed and returned by perl to the SV arena/free SV struct cache. Freed SVs have special patterns in them, like refcount in the 2 billions.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://936297]
Approved by McDarren
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-04-23 11:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found