|
Boost Users : |
Subject: Re: [Boost-users] Copy of a C++ object extended with Boost.Python
From: OvermindDL1 (overminddl1_at_[hidden])
Date: 2009-08-24 16:01:06
On Mon, Aug 24, 2009 at 1:06 PM, 4ian<dark4ian_at_[hidden]> wrote:
> I have a simple C++ object, exposed to python with Boost.python, like
> this :
>
> -------------------------------------------------
> BOOST_PYTHON_MODULE(MyModule)
> {
> class_<MyObject>("MyObject")...
> }
> -------------------------------------------------
>
> I call then python, making an instance of MyObject accessible :
>
> -------------------------------------------------
> MyObject anInstance;
>
> object main_module((handle<>( borrowed( PyImport_AddModule
> ( "__main__" ) ) ) ) );
> object main_namespace = main_module.attr( "__dict__" );
> object myModule( (handle<>(PyImport_ImportModule("MyModule"))) );
> main_namespace["anInstance"] = ptr(&anInstance);
>
> try
> {
> handle<> ignored(( PyRun_String( "anInstance.aNewMember = 1;print
> anInstance.aNewMember;",
> Py_file_input,
> main_namespace.ptr(),
> main_namespace.ptr() ) ) );
> }
> catch ( error_already_set )
> {
> PyErr_Print();
> }
> -------------------------------------------------
>
> You can observe that I've added a member ( aNewMember ) to MyObject
> instance.
> But if I make a copy of my object :
>
> -------------------------------------------------
> MyObject anotherInstance = anInstance;
>
> main_namespace["anotherInstance"] = ptr(&anotherInstance);
>
> try
> {
> handle<> ignored(( PyRun_String( "print
> anotherInstance.aNewMember;",
> Py_file_input,
> main_namespace.ptr(),
> main_namespace.ptr() ) ) );
> }
> catch ( error_already_set )
> {
> PyErr_Print();
> }
> -------------------------------------------------
>
> I have a error saying that MyObject hasn't any "aNewMember" member.
> What I have added with python has not been copied/transfered.
> Is there a workaround to add permanently some new members to wrapped
> objects ?
You are adding an entry to the __dict__ of the wrapper class that
contains the MyObject, but on the line MyObject anotherInstance =
anInstance; you are creating a copy of only the C++ object, not the
wrapper object that has the __dict__. You need to make a copy of it
through the Python bindings, not directly on the C++ copy-constructor
because then you are just copying the MyObject, not the wrapper
object.
I have worked around it by putting a dict in MyObject and exposing it
to python as __dict__ though, just make sure you overload your copy
constructor so you copy the dict too and not just make a copy of the
dict handle, that is important. I did this work-around in an odd way,
not sure it would work directly in Boost.Python, but I would think so.
I think the proper way in Boost.Python would be to (multi-)subclass
your MyObject from that one wrapper helper so you can get the python
self from your class's this, then you can copy the self (not the
handle, again this is important) to the new one as well.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net