in reply to Re: C++ object & PERL garbage collection
in thread C++ object & PERL garbage collection

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?

Replies are listed 'Best First'.
Re^3: C++ object & PERL garbage collection
by syphilis (Archbishop) on Sep 23, 2006 at 02:08 UTC
    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.

      ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊