[C++-sig] set python attribute from C++
David Abrahams
dave at boostpro.com
Thu Jul 17 20:01:06 CEST 2008
on Thu Jul 17 2008, Gennadiy Rozental <rogeeff-AT-gmail.com> wrote:
> David Abrahams <dave <at> boostpro.com> writes:
>> > Why is that by the way? It seems to me that
>> > intrusive_ptr is treated like
>> > distant relative to shared_ptr, while the only real
>> > difference is in storage policy for the counter.
>>
>> It doesn't have a deleter.
>
> Is there some some strong underlying reason why it's can't
> be designed to support it?
There are 2 "it"s in that sentence and I can't tell what either one
refers to.
>> I'm not entirely convinced that you need your own home
>> grown smart pointer in the particular code we're
>> discussing. Any wrapped T is convertible to
>> shared_ptr<T>, no matter what method is used to
>> "hold" the T in the class_<T, ...> declaration.
>
> Not sure i understand what you mean here. Let's say I've
> exported my class like this:
>
> class<A,my_intrusive_smart_ptr<A>,...>
>
>
> Now you are saying I can write the function foo like this:
>
> void foo( shared_ptr<A> o )
> {
> ....
> }
Yes.
> What will happened with memory?
I don't understand the question. Could you be specific?
> Or custom deleter will somehow make it right?
It will be right. It Just Works (TM)
> Tn any case it'll be quite confusing for unaware reader.
What can I tell ya? Sometimes you need to add a few special C++
functions that will be wrapped solely for exposure to Python. Maybe
that's what you should do here.
>> > Ok. Here is my latest attempt schematically:
>> >
> ...
>> > class_<Base,intrusive_ptr<Base>,noncopyable)( "Base" )
>> ^^^^^^^^^^^^^^^^^^^
>>
>> This automatically ensures that you can
>> convert Python objects derived from the Python
>> Base into an intrusive_ptr<Base>. Converting in
>> the other direction works too, but it produces
>> a new Python object.
>
> Yeah, it also produces object of wrong type. If I've
> got bp::object corresponding to the Python class
> Derived(PythonBase) bp::object constructed from
> pointer will hold different object of type PythonBase.
Yes. I notice, by the way, that you didn't specify bases<Base> in your
class_<PythonBase, ...>
>> > }
>> >
>> > private:
>> > bp::object m_object;
>> > };
>> >
>> > class_<PythonBase,PythonBase*,
>> ^^^^^^^^^^^
>> Very dangerous; could lead to leaks of C++
>> objects. However if you want the C++ object
>> to own a Python object, it seems like an option.
>>
>> > ....
>> > ;
>> >
>> > Base*
>> > PythonFactory::create(...)
>> > {
>> > bp::object obj = m_py_type();
>>
>> If m_py_type is the PythonBase Python class,
>> there is nothing managing
>
> No. m_py_type is bp::object corresponding to
> the Derived type (there is whole registration
> phase which I omitted in this discussion)
Then I can't tell whether my statement below is true or not.
>> the C++ PythonBase object's lifetime.
>
> C++ object lifetime is managed by my_intrusive_ptr
> it gets assigned to as a result of create function.
> Not really sure why create function have to return
> raw pointer instead of smart pointer - it predates me.
>
>> The fact that PythonBase is
>> derived from Base and base is held by an
>> intrusive_ptr makes no difference. OTOH, If
>> m_py_type is the "Base" python class, the following
>> extract should fail.
>>
>> > PythonBase* ptr = bp::extract<PythonBase*>( obj );
>
> obj should be of type Derived. This extract should work fine.
OK
>> > On python side I've can now derive from PythonBase:
>> >
>> > class Derived(PythonBase):
>> > pass
>> >
>> > Now i am seems to be able to create instances of
>> > Derived class and set their
>> > field from c++. Does this solution make sence?
>>
>> I'm not 100% certain, but it looks like it will leak
>> C++ PythonBase instances. You might try putting some
>> tracing statements in the ctors and dtors to see if
>> they are actually going away when they should.
>
> Did just that. Seems to be fine in my unit tests.
> Not very comprehensive yet though.
OK
--
Dave Abrahams
BoostPro Computing
http://www.boostpro.com
More information about the Cplusplus-sig
mailing list