in reply to C++ object & PERL garbage collection

A typical strategy is to package your C or C++ thing as a pointer and then make an object out of it. The key here is that perl objects are references so the thing they're pointing to is present as long as the object is. You really ought to post some of your code if you want better help.

<c>package Bar; sub new { my ( $class, $cpp_thing ) = @_; return bless \ $cpp_thing, $class; }</code>

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

  • Comment on Re: C++ object & PERL garbage collection

Replies are listed 'Best First'.
Re^2: C++ object & PERL garbage collection
by Anonymous Monk on Sep 23, 2006 at 01:05 UTC
    i didn't post code because i don't think it's a problem where one can point at a line and say AHA!
    the SWIG module is simply :
    sub method { my @args = @_; $args[0] = tied(%{$args[0]}); my $result = C++CODE::method(@args); return $result; }
    and perl grabs the package with
    use lib (<path>) use (C++ package)

    as one would expect
    my $dsgn = new (c++_object) $dsgn->(method)

    and these lines work IF done in MAIN. if done in a routine and returned to MAIN; it dumps core.
    the object is a PERL HASH; and the address never changes when printed out. at first, i thought that meant the object is still present; but the C++ folks say otherwise.
    i'm thinking it's a namespace issue. another perl coder has declared the object as a global OUR. that seems to work only for the case :
    MAIN my C++object C++object = pckA::routine pckB::routine(C++object) PACKAGEA our C++object routine new C++object return C++object PACKAGEB routine my $C++object = @_ $C++object->method()

    and it ONLY works with OUR! so why is the OUR declaration required? is it a PERL problem with swigged objects or is the C++ code not swig/perl compatable?
      if done in a routine and returned to MAIN; it dumps core

      So the following would dump core:
      my $dsgn = create_new(); $dsgn->(method); sub create_new { my $ret = new (c++_object); return $ret; }
      I wonder what would happen if the reference count were incremented before returning:
      my $dsgn = create_new(); $dsgn->(method); sub create_new { my $ret = new (c++_object); refcnt_inc($ret); return $ret; }
      I don't think there exists a perl function/module that implements a reference count increment - in which case you'd need to do it with Inline::C/XS/SWIG. (I guess SWIG can help out there ... I know nothing about it.) Even if incrementing the reference count does work, that doesn't guarantee that it's the most appropriate thing to do.

      A simple little Inline::C script that increments the reference count:
      use warnings; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'EOC'; void refcnt_inc(SV * sv) { SvREFCNT_inc(sv); } SV * get_refcnt(SV * sv) { return newSVuv(SvREFCNT(sv)); } EOC $x = 1; print get_refcnt($x), "\n"; refcnt_inc($x); print get_refcnt($x), "\n";

      Not sure if there's anything in this post that helps .... :-)

      Cheers,
      Rob

        yes, your code snippet dumps core
        my $dsgn = subA(); $dsgn->method(); sub subA { my $obj = new (c++_object); return $obj; }

        however, a "minor" change to the code works
        my $obj = new (c++_object) subA($obj) sub subA { my ($object) = @_; $object->method(); }

        that's what i mean about up & down in other posts. in other words
        CALLEE can NOT return OBJECT CALLER can ALWAYS pass OBJECT
        and the C++ folks say that it is PERL deleting the object because it is no longer in scope.

        There are functions to increment the reference count of a SV but they're not relevant here.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊