ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> cpp-sig
cpp-sig
Re: [C++-sig] Re: The "return always existing pointer throws dangling error" problem
by Niall Douglas other posts by this author
Oct 21 2003 3:45PM messages near this date
[C++-sig] Re: The "return always existing pointer throws dangling error" problem | [C++-sig] The "return always existing pointer throws dangling error" problem
--PGPMime-Boundary-2DDD351B
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Mail message body

On 21 Oct 2003 at 16:30, David Abrahams wrote:

>  > Let me clarify: From what I understand, most return policies destroy
>  > their associated C++ object instance when its python representation
>  > expires. Mostly that's a copy of the C++ object instance and when
>  > this is the case, the throwing of the error is correct.
>  >
>  > However, if the object instance was allocated by new (and thus its
>  > policy was manage_new_object), 
>  
>  Objects don't have call policies; those are associated with
>  methods/functions.

I had thought that when a function with a return policy returns 
object X, the lifetime ie; validity of X is tied to something else?

>  > return_internal_reference is also different - if you attach lifetime
>  > to self which most do, then when a virtual override in python
>  > returns an internal reference 
>  
>  ?? huh ??
>  A virtual override in Python can only return a Python object.
>  There's no such thing as an "internal reference" in that context.

So when there is a virtual MyObject *MyClass::foo() and my wrapper of 
MyClass overrides default foo() with one calling call_method<MyObject 
*> (self, "foo") then call_method is returning a python object?

How can that possibly be when foo() and all overrides of it must 
return MyObject * (with the exception of covariant returns)?

>  > to either C++ or python code invoking that function
>  
>  When a virtual function overridden in Python is invoked from Python,
>  C++ and BPL are never involved.  The function is simply looked up and
>  called in the usual Python way.  When invoked from C++, the call
>  policies are never involved, since they only apply to wrapped C++
>  functions and a Python function is actually being called.

So you're saying that the _class.def() part has absolutely zero 
relation to the call_method part? They are two bits of absolutely 
unrelated code?

If so, then wow. How could any transient objects created by 
call_method know their contents are destined for C++ world? Maybe 
that's actually the problem?

>  > surely BPL is attaching the lifetime of the internal reference to
>  > the "self" instance and not to the temporary object created during
>  > call_method?  Therefore surely the error is reporting the wrong
>  > thing dangling?
>  
>  Given everything I've written above, what you're saying makes no
>  sense to me.

Once again, I appear to misunderstand how BPL works :(

>  More details about your problem are needed.  My suggestion: for the
>  time-being, stop trying to second-guess the design of Boost.Python and
>  just describe what you're trying to do with a *minimal example*.  If
>  we can't come up with a good solution, then we can talk about design
>  changes.

Done below.

>  > I appreciate that this has been addressed before, and that Dave who
>  > is <censored> has said he's not sure about the correct solution. 
>  > But I can't see how BPL doesn't know where one of its own pointer
>  > containers got its pointer from?

Err, the <censored>  bit was saying a compliment, not anything 
negative in any way whatsoever - I was using a construct borrowed 
from German (consequence of being European). My apologies if you took 
offense at that.

Ok, my problem in condensed form (identical to the two problems as 
referenced in the initial post):

namespace FX {
class FXMetaClass;

class FXObject
{
public:
    static const FXMetaClass metaClass; // metadata for this subclass
    virtual const FXMetaClass *getMetaClass() const { return 
&metaClass; } // metadata for most derived subclass
};

class FXApp : public FXObject
{ ... };
};

struct FX_FXObject_Wrapper: FX::FXObject
{
    const FX::FXMetaClass* getMetaClass() const {
        return call_method< const FX::FXMetaClass* > (self, 
"getMetaClass");
    }

    const FX::FXMetaClass* default_getMetaClass() const {
        return FX::FXObject::getMetaClass();
    }
};

...
void Export_FXObject()
{
    class_< FX::FXObject, FX_FXObject_Wrapper > ("FXObject", init<  
> ())
        .def("getMetaClass", &FX::FXObject::getMetaClass, 
&FX_FXObject_Wrapper::default_getMetaClass, 
return_internal_reference< 1 > ())
        ;
    class_< FX::FXMetaClass > ("FXMetaClass", init< const 
FX::FXMetaClass& > ())
    ...
}

And when you do in python:
a=FXApp()
a.init();

And in FXApp::init(), it queries its metadata:
FXMetaClass *mc=getMetaClass();

... BPL calls FX_FXObject_Wrapper::getMetaClass(), which calls 
python's self.getMetaClass() by call_method (except there isn't one 
and thus it calls the C++ default). However on return from 
call_method, it throws:

ReferenceError: Attempt to return dangling pointer to object of type: 
class FX::FXMetaClass

As I previously said, it's the identical problem as previous posts 
have had. However, in none of those previous posts did I see what a 
solution would be including permitting the python side to subclass 
FXApp say and provide its own custom FXMetaClass.

BTW, the code design of FXObject's and FXMetaClass' is all not mine, 
it is of the underlying GUI toolkit FOX.

Cheers,
Niall




--PGPMime-Boundary-2DDD351B
Content-Type: application/pgp-signature

-----BEGIN PGP MESSAGE-----
Version: idw's PGP-Frontend 4.9.6.1 / 9-2003 + PGP 8.0.2

iQA/AwUBP5W27MEcvDLFGKbPEQJ5cACeK1imOEq9L602hCP0RpHTTd6zcMMAn31w
XyqLorFaBO2XETd/q8zr3yld
=SHNf
-----END PGP MESSAGE-----
--PGPMime-Boundary-2DDD351B--
Attachments:
unknown1
unknown1
unknown2
unknown3
unknown4

Thread:
David Abrahams
Niall Douglas

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved