Re: C++ object & PERL garbage collection
by creamygoodness (Curate) on Sep 23, 2006 at 00:01 UTC
|
I'm not a C++ hacker, but I think I grok the problem. Presumably you have a Perl object which is wrapping a C++ object, and the Perl object's class has a DESTROY function which deletes the C++ object. You can override that DESTROY function and stop it from cleaning up the C++ object, but you'll end up with a memory leak. Another possibility is to save a local copy of the Perl object, using the perlapi function newSVsv, so that when the last Perl-space reference drifts out of scope, you still have a reference keeping it from being destroyed.
Caveat: this is a hard problem, and if you're not familiar with how and when DESTROY gets invoked and does its work, the above advice probably just gives you rope to hang yourself with.
GL,
| [reply] [d/l] |
|
|
| [reply] |
|
|
1) we use SWIG, not XS
the C++ object is a PERL HASH
i can invokes methods on the object with
OBJ->method()
just like a PERL object! :-)
exactly what code do you want to see?
i sort of feel that this is a "philosophical" issue and
not a "coding" mistake
in another reply, i pointed out that OUR works.
based on my limited understanding of OUR;
it seems that OUR prevents PERL from deleting the C++ Object when its being passed around.
but the OUR declaration has to be global
| [reply] [d/l] |
|
|
i have a perl HASH which is a SWIG wrapper of a C++ object.
if i new the object, and pass the reference around
it sometimes works and sometimes fails.
if NEW is in MAIN and passed "down", it works
if NEW is in ROUTINE and passed "up", it fails
and hopefully my usage of up/down is clear!
using namespaces :
if new'd as
MAIN::object, -> works in all "lower" routines
if new'd as
MAIN::routineA::object -> does NOT work in MAIN
you have a interesting point about newSVsv.
it looks like i want something like that.
i need a mechanism for PERL to never delete an object
but i wanted to avoid using a GLOBAL variable that is OUR
maybe that is the purpose of OUR?
| [reply] [d/l] [select] |
|
|
I have to say, I'm very confused by your capitalization. Perl is case-sensitive. There is no OUR, there is only our. Similarly, when you refer to MAIN, I don't know whether you're referring to the default main namespace in Perl, or something having to do with C++ or SWIG.
I can understand your English despite the miscapitalization of words like "I". However, your Perl/C++ leaves me baffled. Can you please reformulate this message to use proper capitalization and punctuation in both the English and the code?
| [reply] [d/l] [select] |
Re: C++ object & PERL garbage collection
by diotalevi (Canon) on Sep 22, 2006 at 23:57 UTC
|
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>
| [reply] |
|
|
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?
| [reply] [d/l] [select] |
|
|
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 | [reply] [d/l] [select] |
|
|
|
|
Re: C++ object & PERL garbage collection
by syphilis (Archbishop) on Sep 23, 2006 at 00:47 UTC
|
if the object is new'd in MAIN; and passed to routines (via @_); no problems
if the object is new'd in a routine; and passed to MAIN (either by return,or global var) problems (dumps core)
the odd thing is that if the object is new'd in a routine and passed to another routine (via @_) no problems.
I can't quite follow that. If "the object is new'd in a routine and passed to another routine (via @_)" doesn't it first need to be passed to "MAIN" - which, you say, dumps core ? That is, how do you pass the object that was "new'd in a routine" to "another routine (via @_)" without first passing that object to "MAIN" ?
Sorry if I'm being dumb :-)
Anyway, seems to me that the issue is probably one that can only properly be fixed in the C++/XS code (rather than your perl code) ... but it's hard to tell from the info you've provided.
Cheers, Rob | [reply] |
|
|
but routines can call other routines, without first returning to MAIN, true?
MAIN
&routineA
ROUTINEA
&routineB
ROUTINEB
.....
so a flow that works is :
MAIN
new C++object
routineA(C++object)
routineB(C++object)
but a flow that does NOT work is :
MAIN
my C++object = routineA
C++object->method
ROUTINEA
my C++object = new C++design
return C++object
yes, i agree with your last statement.
( that it is a C++ usage/style issue )
although we use SWIG, instead of XS.
| [reply] [d/l] [select] |