Discussion:
[C++-sig] express pointer ownership
MM
2015-08-13 09:24:42 UTC
Permalink
I have the following class:

class T {
};
// T has been exposed to python with class_

and free function:

void add_T( T* );

Ownership of the T* is taken by this C++ function.


If I create an instance of the python version of T, how do I "def" the
add_T function?

def("add_T", add_T)

fails to compile.
MM
2015-08-13 10:58:42 UTC
Permalink
Post by MM
class T {
};
// T has been exposed to python with class_
void add_T( T* );
Ownership of the T* is taken by this C++ function.
If I create an instance of the python version of T, how do I "def" the
add_T function?
def("add_T", add_T)
fails to compile.
Apologies. This compiled correctly.

This function:

const T* get_T( const std::string& name );

failed to compile.

so the T pointer is owner by a container in the c++ world, it gets stored
there by add_T,
then the get_T returns a raw pointer to it. I want to tell python to let
c++ manage it.
Stefan Seefeld
2015-08-13 11:01:37 UTC
Permalink
Post by MM
class T {
};
// T has been exposed to python with class_
void add_T( T* );
Ownership of the T* is taken by this C++ function.
If I create an instance of the python version of T, how do I "def"
the add_T function?
def("add_T", add_T)
fails to compile.
Apologies. This compiled correctly.
const T* get_T( const std::string& name );
failed to compile.
so the T pointer is owner by a container in the c++ world, it gets
stored there by add_T,
then the get_T returns a raw pointer to it. I want to tell python to
let c++ manage it.
Sounds like you want to use the "return_internal_reference" call policy
(see
http://boostorg.github.io/python/doc/html/tutorial/tutorial/functions.html#tutorial.functions.call_policies).

Stefan
--
...ich hab' noch einen Koffer in Berlin...
MM
2015-08-13 11:26:41 UTC
Permalink
Post by Stefan Seefeld
Post by MM
class T {
};
// T has been exposed to python with class_
void add_T( T* );
Ownership of the T* is taken by this C++ function.
If I create an instance of the python version of T, how do I "def"
the add_T function?
def("add_T", add_T)
fails to compile.
Apologies. This compiled correctly.
const T* get_T( const std::string& name );
failed to compile.
so the T pointer is owner by a container in the c++ world, it gets
stored there by add_T,
then the get_T returns a raw pointer to it. I want to tell python to
let c++ manage it.
Sounds like you want to use the "return_internal_reference" call policy
(see
http://boostorg.github.io/python/doc/html/tutorial/tutorial/functions.html#tutorial.functions.call_policies
).
Stefan
That policy says:

"Ties lifetime of one argument to that of result"

The argument of my function is just the string.... Really its lifetime
doesn't matter....
In the context of a call from python:

t = get_T( 'name1' )

At some point, a std::string temporary must be constructed, holding
'name1'? and then get_T uses it for lookup.
Once get_T returns the const T*, it doesn't care about it anymore.

What I want to express is:

The t returned by the python function should refer to object T held in c++
memory, and for instance

del t

should not delete the actual T object in c++ memory

Should I still use "return_internal_reference" ?
Alex Mohr
2015-08-13 16:09:49 UTC
Permalink
Post by MM
The t returned by the python function should refer to object T held in
c++ memory, and for instance
del t
should not delete the actual T object in c++ memory
Should I still use "return_internal_reference" ?
You can use reference_existing_object
(http://www.boost.org/doc/libs/1_59_0/libs/python/doc/v2/reference_existing_object.html)

But as the docs say, that can be dangerous since if I do 't = get_T()'
in python and then sometime later C++ deletes the object that t refers
to, now I have a dangling pointer. If I try to use 't' in python now I
have undefined behavior (and likely crash).

Alex

Loading...