Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

perl embedded in C++: how to undefine perl objects that are blessed references to C++ objects when the C++ object destructs

by kingkongrevenge (Scribe)
on Sep 19, 2009 at 15:20 UTC ( [id://796297]=perlquestion: print w/replies, xml ) Need Help??

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

I have perl embedded in a C++ program. Various C++ objects are wrapped up with XS interfaces. The objects live on the C++ side of things; the perl scripting bits just need to talk to the C++ objects for small time slices. Perl functions get called with the relevant objects as arguments. This all works fine.

My problem is how to invalidate (set to undef) all scalar references to a C++ object when the object is destroyed on the C++ side. $some_cpp_obj->do_it; will crash with memory access violations if the relevant object has been destroyed. I want the C++ destructor to reach into the perl interpreter and set $some_cpp_obj to undef. Any copies of $some_cpp_obj also need to be undefined.

I guess conceptually I want something like *sv = PL_sv_undef, so all SvRefs to that piece of memory now point to undef. Except I think that would crash the application. My best guess is I actually need to scan the whole interpreter for SvRefs for the now invalid pointer.

sub some_event { my $cpp_obj = shift; # It's an arbitrary time later. We have no g +uaranty # the object is still around. return unless $cpp_obj; # I want this to work: if the underlying C +++ object # is gone $cpp_obj should return undef in scalar context. # Do stuff that will blow up if $cpp_obj is gone. # ... } sub i_get_called_from_cpp_code { my ($cpp_obj, $time) = @_; my $event = sub { some_event($cpp_obj) }; Scheduler::new_event($time + 10, $event); }

I guess another way to represent the problem in pure perl is thusly.

package Whatever; sub new { my $self = 0; bless \$self } # $self is Whatever=SCALAR(0x97 +42b30) sub blah { my $self = shift; say $self } package main; my $a = Whatever->new; my $b = $a; # I want to kill $a such that $b is now also undef. How? $a->blah; $$a = undef; # I really want to undefine ALL references to Whatever=SC +ALAR(0x9742b30) $b->blah; # This should die.
  • Comment on perl embedded in C++: how to undefine perl objects that are blessed references to C++ objects when the C++ object destructs
  • Select or Download Code

Replies are listed 'Best First'.
Re: perl embedded in C++: how to undefine perl objects that are blessed references to C++ objects when the C++ object destructs
by BrowserUk (Patriarch) on Sep 19, 2009 at 15:36 UTC

    You could do the double indirection thing.

    That is, instead of passing the SV that wraps your C++ object to the Perl code, pass an SvRV that points to that SV. Then your Perl code would have to indirect through the SvRV to get at the object

    my $cppOref = shift; return unless $$cppOref; $$cppOref->whatever

    That way, your C++ destructor can undef the SV, and any copies of the SvRV that the Perl code has retain will point to undef. It won't stop someone making a copy of the dereferenced SV: my $sneaky = $$cppOref; and falling in a heap by trying to use it later, but that's an education thing.


    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.
      I'll probably end up doing that. But if it's possible to do what I originally described (reach into the interpreter and undefine now invalid SV*) I'd still like to pursue it.

        I'm far from expert on Perl internals, but given the way Perl allocates it variables I think that this would necessitate scanning the entire stack and entire heap attempting to find values in memory locations that 'look like' the SV* in question. Besides being rather slow, it is fraught with dangers.

        What would you search for? How would you distinguish between four bytes that contain the address of your C++ object, and four bytes that contain a number that coincidentally matches the address of your C++ object?

        And what benefit would you get? If the Perl code is going to indirect through a retained SV* and so trap; if you set it to undef, it is still going to indirect through it and die anyway. It might be a less violent death, but there is still no way for the Perl code to reasonably continue.


        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: perl embedded in C++: how to undefine perl objects that are blessed references to C++ objects when the C++ object destructs
by Joost (Canon) on Sep 19, 2009 at 16:01 UTC
    I agree with the suggestion above of using double indirection to solve this problem. For one, it's easy to implement and second it's probably a lot more efficient than finding all references in use and resetting them.

    AFAIK you can automate the dereferencing process (at the XS side) using typemaps, so you won't have to write any additional XS or perl code to implement this strategy for a straight C++ to perl mapping.

      I guess I can also use overload to overload the scalar dereference, so it's transparent.

Log In?
Username:
Password:

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

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

    No recent polls found