[C++-sig] errors compiling Boost Python example

2012-07-05 Thread Joel Uckelman
I'm trying to compile the example from the Boost Python docs without
success.

hello.cpp:

  #include 

  char const * const greet() {
return "hello, world";
  }

  BOOST_PYTHON_MODULE(hello_ext) {
using namespace boost::python;
def("greet", greet);
  }

I have Boost 1.48, Python 2.7, and gcc 4.7.0.

When I do this:

  g++ -fPIC -I/usr/include/python2.7 -c -o hello.o hello.cpp

I get the following errors:

In file included from 
/usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47:0,
 from /usr/include/boost/python/detail/invoke.hpp:63,
 from /usr/include/boost/python/detail/caller.hpp:16,
 from /usr/include/boost/python/object/function_handle.hpp:8,
 from /usr/include/boost/python/converter/arg_to_python.hpp:19,
 from /usr/include/boost/python/call.hpp:15,
 from /usr/include/boost/python/object_core.hpp:14,
 from /usr/include/boost/python/args.hpp:25,
 from /usr/include/boost/python.hpp:11,
 from hello.cpp:1:
/usr/include/boost/python/detail/invoke.hpp: In instantiation of ‘PyObject* 
boost::python::detail::invoke(boost::python::detail::invoke_tag_, 
const RC&, F&) [with RC = 
boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning; F = const char* const (*)(); PyObject = _object]’:
/usr/include/boost/python/detail/caller.hpp:223:13:   required from 
‘PyObject* boost::python::detail::caller_arity<0u>::impl::operator()(PyObject*, PyObject*) [with F = const char* const (*)(); 
Policies = boost::python::default_call_policies; Sig = 
boost::mpl::vector1; PyObject = _object]’
/usr/include/boost/python/object/py_function.hpp:38:33:   required from 
‘PyObject* 
boost::python::objects::caller_py_function_impl::operator()(PyObject*, 
PyObject*) [with Caller = boost::python::detail::caller >; PyObject = _object]’
hello.cpp:10:1:   required from here
/usr/include/boost/python/detail/invoke.hpp:75:19: error: no match for call to 
‘(const 
boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning) (const char*)’
In file included from /usr/include/boost/python/object/function_handle.hpp:8:0,
 from /usr/include/boost/python/converter/arg_to_python.hpp:19,
 from /usr/include/boost/python/call.hpp:15,
 from /usr/include/boost/python/object_core.hpp:14,
 from /usr/include/boost/python/args.hpp:25,
 from /usr/include/boost/python.hpp:11,
 from hello.cpp:1:
/usr/include/boost/python/detail/caller.hpp: In instantiation of ‘static 
const PyTypeObject* 
boost::python::detail::converter_target_type::get_pytype() 
[with ResultConverter = 
boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning; PyTypeObject = _typeobject]’:
/usr/include/boost/python/detail/caller.hpp:242:13:   required from ‘static 
boost::python::detail::py_func_sig_info 
boost::python::detail::caller_arity<0u>::impl::signature() 
[with F = const char* const (*)(); Policies = 
boost::python::default_call_policies; Sig = boost::mpl::vector1]’
/usr/include/boost/python/object/py_function.hpp:48:35:   required from 
‘boost::python::detail::py_func_sig_info 
boost::python::objects::caller_py_function_impl::signature() const 
[with Caller = boost::python::detail::caller 
>]’
hello.cpp:10:1:   required from here
/usr/include/boost/python/detail/caller.hpp:102:109: error: ‘struct 
boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning’ has no member named ‘get_pytype’
In file included from 
/usr/include/boost/python/converter/pytype_function.hpp:10:0,
 from /usr/include/boost/python/to_python_indirect.hpp:16,
 from /usr/include/boost/python/converter/arg_to_python.hpp:10,
 from /usr/include/boost/python/call.hpp:15,
 from /usr/include/boost/python/object_core.hpp:14,
 from /usr/include/boost/python/args.hpp:25,
 from /usr/include/boost/python.hpp:11,
 from hello.cpp:1:
/usr/include/boost/python/detail/unwind_type.hpp: In instantiation of 
‘typename Generator::result_type 
boost::python::detail::unwind_type(boost::type*, Generator*) [with Generator 
= boost::python::converter::detail::unwind_type_id_helper; U = const char* 
const; typename Generator::result_type = boost::python::type_info]’:
/usr/include/boost/python/converter/pytype_function.hpp:45:74:   required from 
‘boost::python::type_info 
boost::python::converter::detail::unwind_type_id_(boost::type*, 
mpl_::false_*) [with T = const char* const; mpl_::false_ = 
mpl_::bool_]’
/usr/include/boost/python/converter/pytype_function.hpp:68:13:   required from 
‘static const PyTypeObject* 
boost::python::converter::expected_pytype_for_arg::get_pytype() [with T = 
const char* const; PyTypeObject = _typeob

[C++-sig] Instance ownership transfer in constructor.

2012-07-05 Thread Jani Tiainen

Hi,

I'm new to python.boost library and I'm trying to use it to wrap a third 
party library. Everything else I've managed to get working - thanks to 
excellent library and lot of examples I've found around a net.


Only thing I can't get working properly is instance ownership transfer 
in constructor.


So classes in library are defined like follows:

class Owner {
...
}

class Data {
Data(Owner *owner); // <-- Here happens ownership transfer.
}


Python code is like follows:

owner = Owner()
data_1 = Data(owner)
data_2 = Data(owner)

So when Python script stops runnning it causes crash due the fact that 
I've data objects are automatically destroyed by Owner-class but Python 
deletes them by using Data-class destructor (which shouldn't happen ever).


--
Jani Tiainen

- Well planned is half done and a half done has been sufficient before...

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] errors compiling Boost Python example

2012-07-05 Thread Sybren A . Stüvel
Hi Joel,

On 5 July 2012 12:21, Joel Uckelman  wrote:

> I'm trying to compile the example from the Boost Python docs without
> success. [...]
>

There are many ways in which you can fix this. I think the easiest one from
an I'm-just-starting-so-please-give-me-a-simple-hello-world-program point
of view is to replace "char const *" with "std::string". That works on my
machine (Python 3.2, VS2010, Boost 1.48).

Best,
-- 
Sybren A. Stüvel

http://stuvel.eu/
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] errors compiling Boost Python example

2012-07-05 Thread Joel Uckelman
Thus spake Sybren A. Stüvel:
> 
> Hi Joel,
> 
> On 5 July 2012 12:21, Joel Uckelman  wrote:
> 
> > I'm trying to compile the example from the Boost Python docs without
> > success. [...]
> >
> 
> There are many ways in which you can fix this. I think the easiest one from
> an I'm-just-starting-so-please-give-me-a-simple-hello-world-program point
> of view is to replace "char const *" with "std::string". That works on my
> machine (Python 3.2, VS2010, Boost 1.48).

Yes, I can compile if I switch to std::string as the return type. Thanks
for that.

Do you know why Boost Python complains about returning a char const*?
It's a strange thing to have for the first example in the docs if it
won't compile.
 
-- 
J.
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] errors compiling Boost Python example

2012-07-05 Thread Sybren A . Stüvel
On 5 July 2012 13:10, Joel Uckelman  wrote:

> Do you know why Boost Python complains about returning a char const*?
>

When returning a pointer, you have to tell Boost::Python what to do with
it. The most important issue is one of ownership. Once the pointer has been
returned as a Python object in the Python world, and that object goes out
of scope, what should happen with the pointer? Is it owned by Python and
should the pointed-to memory be deallocated too? Or was it still owned by
the function that returned it? This is what you have to tell Boost::Python
before it allows you to return pointers. And this is also why I looked for
a solution that didn't involve pointers - much easier to understand as a
first example.


> It's a strange thing to have for the first example in the docs if it won't
> compile.


I agree. Personally I can't do anything about that, though.

-- 
Sybren A. Stüvel

http://stuvel.eu/
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] errors compiling Boost Python example

2012-07-05 Thread Ralf Grosse-Kunstleve
It looks like you inserted an extra const (I don't see it in the current
tutorial) ...

char const * const greet() {

It should work if you remove it.

Ralf


On Thu, Jul 5, 2012 at 3:21 AM, Joel Uckelman  wrote:

> I'm trying to compile the example from the Boost Python docs without
> success.
>
> hello.cpp:
>
>   #include 
>
>   char const * const greet() {
> return "hello, world";
>   }
>
>   BOOST_PYTHON_MODULE(hello_ext) {
> using namespace boost::python;
> def("greet", greet);
>   }
>
> I have Boost 1.48, Python 2.7, and gcc 4.7.0.
>
> When I do this:
>
>   g++ -fPIC -I/usr/include/python2.7 -c -o hello.o hello.cpp
>
> I get the following errors:
>
> In file included from
> /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47:0,
>  from /usr/include/boost/python/detail/invoke.hpp:63,
>  from /usr/include/boost/python/detail/caller.hpp:16,
>  from
> /usr/include/boost/python/object/function_handle.hpp:8,
>  from
> /usr/include/boost/python/converter/arg_to_python.hpp:19,
>  from /usr/include/boost/python/call.hpp:15,
>  from /usr/include/boost/python/object_core.hpp:14,
>  from /usr/include/boost/python/args.hpp:25,
>  from /usr/include/boost/python.hpp:11,
>  from hello.cpp:1:
> /usr/include/boost/python/detail/invoke.hpp: In instantiation of
> ‘PyObject*
> boost::python::detail::invoke(boost::python::detail::invoke_tag_ false>, const RC&, F&) [with RC =
> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning char* const>; F = const char* const (*)(); PyObject = _object]’:
> /usr/include/boost/python/detail/caller.hpp:223:13:   required from
> ‘PyObject* boost::python::detail::caller_arity<0u>::impl Sig>::operator()(PyObject*, PyObject*) [with F = const char* const (*)();
> Policies = boost::python::default_call_policies; Sig =
> boost::mpl::vector1; PyObject = _object]’
> /usr/include/boost/python/object/py_function.hpp:38:33:   required from
> ‘PyObject*
> boost::python::objects::caller_py_function_impl::operator()(PyObject*,
> PyObject*) [with Caller = boost::python::detail::caller (*)(), boost::python::default_call_policies, boost::mpl::vector1 char* const> >; PyObject = _object]’
> hello.cpp:10:1:   required from here
> /usr/include/boost/python/detail/invoke.hpp:75:19: error: no match for
> call to ‘(const
> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning char* const>) (const char*)’
> In file included from
> /usr/include/boost/python/object/function_handle.hpp:8:0,
>  from
> /usr/include/boost/python/converter/arg_to_python.hpp:19,
>  from /usr/include/boost/python/call.hpp:15,
>  from /usr/include/boost/python/object_core.hpp:14,
>  from /usr/include/boost/python/args.hpp:25,
>  from /usr/include/boost/python.hpp:11,
>  from hello.cpp:1:
> /usr/include/boost/python/detail/caller.hpp: In instantiation of ‘static
> const PyTypeObject*
> boost::python::detail::converter_target_type::get_pytype()
> [with ResultConverter =
> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning char* const>; PyTypeObject = _typeobject]’:
> /usr/include/boost/python/detail/caller.hpp:242:13:   required from
> ‘static boost::python::detail::py_func_sig_info
> boost::python::detail::caller_arity<0u>::impl Sig>::signature() [with F = const char* const (*)(); Policies =
> boost::python::default_call_policies; Sig = boost::mpl::vector1 const>]’
> /usr/include/boost/python/object/py_function.hpp:48:35:   required from
> ‘boost::python::detail::py_func_sig_info
> boost::python::objects::caller_py_function_impl::signature() const
> [with Caller = boost::python::detail::caller boost::python::default_call_policies, boost::mpl::vector1 const> >]’
> hello.cpp:10:1:   required from here
> /usr/include/boost/python/detail/caller.hpp:102:109: error: ‘struct
> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning char* const>’ has no member named ‘get_pytype’
> In file included from
> /usr/include/boost/python/converter/pytype_function.hpp:10:0,
>  from /usr/include/boost/python/to_python_indirect.hpp:16,
>  from
> /usr/include/boost/python/converter/arg_to_python.hpp:10,
>  from /usr/include/boost/python/call.hpp:15,
>  from /usr/include/boost/python/object_core.hpp:14,
>  from /usr/include/boost/python/args.hpp:25,
>  from /usr/include/boost/python.hpp:11,
>  from hello.cpp:1:
> /usr/include/boost/python/detail/unwind_type.hpp: In instantiation of
> ‘typename Generator::result_type
> boost::python::detail::unwind_type(boost::type*, Generator*) [with
> Generator = boost::python::converter::detail::unwind_type_id_helper; U =
> const char* const;

Re: [C++-sig] errors compiling Boost Python example

2012-07-05 Thread Ralf Grosse-Kunstleve
Oops, I meant to mark the extra const with a color:

char const * *const* greet() {


On Thu, Jul 5, 2012 at 7:57 AM, Ralf Grosse-Kunstleve wrote:

> It looks like you inserted an extra const (I don't see it in the current
> tutorial) ...
>
> char const * const greet() {
>
> It should work if you remove it.
>
> Ralf
>
>
> On Thu, Jul 5, 2012 at 3:21 AM, Joel Uckelman  wrote:
>
>> I'm trying to compile the example from the Boost Python docs without
>> success.
>>
>> hello.cpp:
>>
>>   #include 
>>
>>   char const * const greet() {
>> return "hello, world";
>>   }
>>
>>   BOOST_PYTHON_MODULE(hello_ext) {
>> using namespace boost::python;
>> def("greet", greet);
>>   }
>>
>> I have Boost 1.48, Python 2.7, and gcc 4.7.0.
>>
>> When I do this:
>>
>>   g++ -fPIC -I/usr/include/python2.7 -c -o hello.o hello.cpp
>>
>> I get the following errors:
>>
>> In file included from
>> /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47:0,
>>  from /usr/include/boost/python/detail/invoke.hpp:63,
>>  from /usr/include/boost/python/detail/caller.hpp:16,
>>  from
>> /usr/include/boost/python/object/function_handle.hpp:8,
>>  from
>> /usr/include/boost/python/converter/arg_to_python.hpp:19,
>>  from /usr/include/boost/python/call.hpp:15,
>>  from /usr/include/boost/python/object_core.hpp:14,
>>  from /usr/include/boost/python/args.hpp:25,
>>  from /usr/include/boost/python.hpp:11,
>>  from hello.cpp:1:
>> /usr/include/boost/python/detail/invoke.hpp: In instantiation of
>> ‘PyObject*
>> boost::python::detail::invoke(boost::python::detail::invoke_tag_> false>, const RC&, F&) [with RC =
>> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning> char* const>; F = const char* const (*)(); PyObject = _object]’:
>> /usr/include/boost/python/detail/caller.hpp:223:13:   required from
>> ‘PyObject* boost::python::detail::caller_arity<0u>::impl> Sig>::operator()(PyObject*, PyObject*) [with F = const char* const (*)();
>> Policies = boost::python::default_call_policies; Sig =
>> boost::mpl::vector1; PyObject = _object]’
>> /usr/include/boost/python/object/py_function.hpp:38:33:   required from
>> ‘PyObject*
>> boost::python::objects::caller_py_function_impl::operator()(PyObject*,
>> PyObject*) [with Caller = boost::python::detail::caller> (*)(), boost::python::default_call_policies, boost::mpl::vector1> char* const> >; PyObject = _object]’
>> hello.cpp:10:1:   required from here
>> /usr/include/boost/python/detail/invoke.hpp:75:19: error: no match for
>> call to ‘(const
>> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning> char* const>) (const char*)’
>> In file included from
>> /usr/include/boost/python/object/function_handle.hpp:8:0,
>>  from
>> /usr/include/boost/python/converter/arg_to_python.hpp:19,
>>  from /usr/include/boost/python/call.hpp:15,
>>  from /usr/include/boost/python/object_core.hpp:14,
>>  from /usr/include/boost/python/args.hpp:25,
>>  from /usr/include/boost/python.hpp:11,
>>  from hello.cpp:1:
>> /usr/include/boost/python/detail/caller.hpp: In instantiation of ‘static
>> const PyTypeObject*
>> boost::python::detail::converter_target_type::get_pytype()
>> [with ResultConverter =
>> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning> char* const>; PyTypeObject = _typeobject]’:
>> /usr/include/boost/python/detail/caller.hpp:242:13:   required from
>> ‘static boost::python::detail::py_func_sig_info
>> boost::python::detail::caller_arity<0u>::impl> Sig>::signature() [with F = const char* const (*)(); Policies =
>> boost::python::default_call_policies; Sig = boost::mpl::vector1> const>]’
>> /usr/include/boost/python/object/py_function.hpp:48:35:   required from
>> ‘boost::python::detail::py_func_sig_info
>> boost::python::objects::caller_py_function_impl::signature() const
>> [with Caller = boost::python::detail::caller> boost::python::default_call_policies, boost::mpl::vector1> const> >]’
>> hello.cpp:10:1:   required from here
>> /usr/include/boost/python/detail/caller.hpp:102:109: error: ‘struct
>> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning> char* const>’ has no member named ‘get_pytype’
>> In file included from
>> /usr/include/boost/python/converter/pytype_function.hpp:10:0,
>>  from /usr/include/boost/python/to_python_indirect.hpp:16,
>>  from
>> /usr/include/boost/python/converter/arg_to_python.hpp:10,
>>  from /usr/include/boost/python/call.hpp:15,
>>  from /usr/include/boost/python/object_core.hpp:14,
>>  from /usr/include/boost/python/args.hpp:25,
>>  from /usr/include/boost/python.hpp:11,
>>  from hello.cpp:1:
>> /u

Re: [C++-sig] errors compiling Boost Python example

2012-07-05 Thread Joel Uckelman
Thus spake Ralf Grosse-Kunstleve:
> 
> It looks like you inserted an extra const (I don't see it in the current
> tutorial) ...
> 
> char const * const greet() {
> 
> It should work if you remove it.

Ha! You're correct. The example program was so short that I just retyped
it, and I made the pointer const out of habit without noticing. Now all
makes sense. Thanks!
 
-- 
J.
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] Instance ownership transfer in constructor.

2012-07-05 Thread John Reid
On 05/07/12 11:49, Jani Tiainen wrote:
> Hi,
> 
> I'm new to python.boost library and I'm trying to use it to wrap a third
> party library. Everything else I've managed to get working - thanks to
> excellent library and lot of examples I've found around a net.
> 
> Only thing I can't get working properly is instance ownership transfer
> in constructor.
> 
> So classes in library are defined like follows:
> 
> class Owner {
> ...
> }
> 
> class Data {
> Data(Owner *owner); // <-- Here happens ownership transfer.
> }
> 
> 
> Python code is like follows:
> 
> owner = Owner()
> data_1 = Data(owner)
> data_2 = Data(owner)
> 
> So when Python script stops runnning it causes crash due the fact that
> I've data objects are automatically destroyed by Owner-class but Python
> deletes them by using Data-class destructor (which shouldn't happen ever).
> 

If I understand you correctly then you want the owner object to remain
alive at least as long as data_1 and data_2? If so you could use
with_custodian_and_ward:
http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2/with_custodian_and_ward.html

For example something like the following should work:

namespace py = boost::python;
py::class_<
...
> my_class(
"Data",
"docstring.",
py::init< Owner * >( "Constructor." )[
py::with_custodian_and_ward< 1, 2 >()
]
);

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] Instance ownership transfer in constructor.

2012-07-05 Thread Jani Tiainen
I want to do it another way around:

Instance of Owner should hold reference to data_1 and data_2 as long as
owner is alive.

Now following happens:
owner = Owner()
data_1 = Data(owner) # data_1 ownership is transferred to owner object
data_2 = Data(owner) # data_2 ownership is transferred to owner object

print owner.get_data_objects()

, 

del data_1
del data_2

print owner.get_data_objects()
# Crash because data_1 and data_2 are deleted even owner should still hold
the reference.

I tried to do it like
http://www.boost.org/doc/libs/1_49_0/libs/python/test/injected.cpp  but it
didn't worked for me.

On Thu, Jul 5, 2012 at 7:00 PM, John Reid wrote:

> On 05/07/12 11:49, Jani Tiainen wrote:
> > Hi,
> >
> > I'm new to python.boost library and I'm trying to use it to wrap a third
> > party library. Everything else I've managed to get working - thanks to
> > excellent library and lot of examples I've found around a net.
> >
> > Only thing I can't get working properly is instance ownership transfer
> > in constructor.
> >
> > So classes in library are defined like follows:
> >
> > class Owner {
> > ...
> > }
> >
> > class Data {
> > Data(Owner *owner); // <-- Here happens ownership transfer.
> > }
> >
> >
> > Python code is like follows:
> >
> > owner = Owner()
> > data_1 = Data(owner)
> > data_2 = Data(owner)
> >
> > So when Python script stops runnning it causes crash due the fact that
> > I've data objects are automatically destroyed by Owner-class but Python
> > deletes them by using Data-class destructor (which shouldn't happen
> ever).
> >
>
> If I understand you correctly then you want the owner object to remain
> alive at least as long as data_1 and data_2? If so you could use
> with_custodian_and_ward:
>
> http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2/with_custodian_and_ward.html
>
> For example something like the following should work:
>
> namespace py = boost::python;
> py::class_<
> ...
> > my_class(
> "Data",
> "docstring.",
> py::init< Owner * >( "Constructor." )[
> py::with_custodian_and_ward< 1, 2 >()
> ]
> );
>
> ___
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>



-- 
Jani Tiainen

- Well planned is half done, and a half done has been sufficient before...
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] Instance ownership transfer in constructor.

2012-07-05 Thread Holger Brandsmeier
Jani,

ok what you want to do is quite a lot more intrusive, so you need some
more involved methods, but it should be possible. I would do it by
noting the following
 - data_1 is published to python as a boost::shared_ptr (default
holder type)
 - usually it is difficult for a class member function, to obtain a
shared_ptr<> to itself, i.e. something like `this` but not of type
Data* but of boost::shared_ptr.
 - fortunately there is something supported by boost itself, called
`enable_shared_from_this`, see
  http://stackoverflow.com/questions/142391/getting-a-boostshared-ptr-for-this
 - Now you want `owner` to hold on to this `shared_ptr` which
ensures that `data_1` does not get deleted before `owner`, you can do
this by
  owner->setData( shared_from_this() )
in any member function of `Data`.
 - Note that I _think_ that you are not allowed to use
`shared_from_this()` in the constructor itself, so you might have to
use boost::pythons `make_constructor` to make an ordinary member /
non-member function behave as the constructor in python.

Maybe someone has a quicker way of doing this, but remember that this
is exactly the use case that `shared_ptr` are made for,
Holger


On Thu, Jul 5, 2012 at 6:47 PM, Jani Tiainen  wrote:
> I want to do it another way around:
>
> Instance of Owner should hold reference to data_1 and data_2 as long as
> owner is alive.
>
> Now following happens:
> owner = Owner()
> data_1 = Data(owner) # data_1 ownership is transferred to owner object
> data_2 = Data(owner) # data_2 ownership is transferred to owner object
>
> print owner.get_data_objects()
>
> , 
>
> del data_1
> del data_2
>
> print owner.get_data_objects()
> # Crash because data_1 and data_2 are deleted even owner should still hold
> the reference.
>
> I tried to do it like
> http://www.boost.org/doc/libs/1_49_0/libs/python/test/injected.cpp  but it
> didn't worked for me.
>
>
> On Thu, Jul 5, 2012 at 7:00 PM, John Reid 
> wrote:
>>
>> On 05/07/12 11:49, Jani Tiainen wrote:
>> > Hi,
>> >
>> > I'm new to python.boost library and I'm trying to use it to wrap a third
>> > party library. Everything else I've managed to get working - thanks to
>> > excellent library and lot of examples I've found around a net.
>> >
>> > Only thing I can't get working properly is instance ownership transfer
>> > in constructor.
>> >
>> > So classes in library are defined like follows:
>> >
>> > class Owner {
>> > ...
>> > }
>> >
>> > class Data {
>> > Data(Owner *owner); // <-- Here happens ownership transfer.
>> > }
>> >
>> >
>> > Python code is like follows:
>> >
>> > owner = Owner()
>> > data_1 = Data(owner)
>> > data_2 = Data(owner)
>> >
>> > So when Python script stops runnning it causes crash due the fact that
>> > I've data objects are automatically destroyed by Owner-class but Python
>> > deletes them by using Data-class destructor (which shouldn't happen
>> > ever).
>> >
>>
>> If I understand you correctly then you want the owner object to remain
>> alive at least as long as data_1 and data_2? If so you could use
>> with_custodian_and_ward:
>>
>> http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2/with_custodian_and_ward.html
>>
>> For example something like the following should work:
>>
>> namespace py = boost::python;
>> py::class_<
>> ...
>> > my_class(
>> "Data",
>> "docstring.",
>> py::init< Owner * >( "Constructor." )[
>> py::with_custodian_and_ward< 1, 2 >()
>> ]
>> );
>>
>> ___
>> Cplusplus-sig mailing list
>> [email protected]
>> http://mail.python.org/mailman/listinfo/cplusplus-sig
>
>
>
>
> --
> Jani Tiainen
>
> - Well planned is half done, and a half done has been sufficient before...
>
>
> ___
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] Instance ownership transfer in constructor.

2012-07-05 Thread Jani Tiainen

Hi,

I'm still strugling with this whole thingy so I came up with more 
concrete example I'm trying to achieve:


http://pastebin.com/dVRfT56x


And in python code I do like this:

owner = Owner()
data = Data(owner)

After script is finished I get warning message that Data destructor 
shouldn't be called directly. And then python crashes due memory corruption.


I've tried to make usage of shared_ptr but no luck and I didn't 
understood how to apply shared_ptr_for_this.


(NOTE: in my case all classes are from 3rd party library that I have no 
control over)


5.7.2012 20:44, Holger Brandsmeier kirjoitti:

Jani,

ok what you want to do is quite a lot more intrusive, so you need some
more involved methods, but it should be possible. I would do it by
noting the following
  - data_1 is published to python as a boost::shared_ptr (default
holder type)
  - usually it is difficult for a class member function, to obtain a
shared_ptr<> to itself, i.e. something like `this` but not of type
Data* but of boost::shared_ptr.
  - fortunately there is something supported by boost itself, called
`enable_shared_from_this`, see
   http://stackoverflow.com/questions/142391/getting-a-boostshared-ptr-for-this
  - Now you want `owner` to hold on to this `shared_ptr` which
ensures that `data_1` does not get deleted before `owner`, you can do
this by
   owner->setData( shared_from_this() )
in any member function of `Data`.
  - Note that I _think_ that you are not allowed to use
`shared_from_this()` in the constructor itself, so you might have to
use boost::pythons `make_constructor` to make an ordinary member /
non-member function behave as the constructor in python.

Maybe someone has a quicker way of doing this, but remember that this
is exactly the use case that `shared_ptr` are made for,
Holger


On Thu, Jul 5, 2012 at 6:47 PM, Jani Tiainen  wrote:

I want to do it another way around:

Instance of Owner should hold reference to data_1 and data_2 as long as
owner is alive.

Now following happens:
owner = Owner()
data_1 = Data(owner) # data_1 ownership is transferred to owner object
data_2 = Data(owner) # data_2 ownership is transferred to owner object

print owner.get_data_objects()

, 

del data_1
del data_2

print owner.get_data_objects()
# Crash because data_1 and data_2 are deleted even owner should still hold
the reference.

I tried to do it like
http://www.boost.org/doc/libs/1_49_0/libs/python/test/injected.cpp  but it
didn't worked for me.


On Thu, Jul 5, 2012 at 7:00 PM, John Reid 
wrote:


On 05/07/12 11:49, Jani Tiainen wrote:

Hi,

I'm new to python.boost library and I'm trying to use it to wrap a third
party library. Everything else I've managed to get working - thanks to
excellent library and lot of examples I've found around a net.

Only thing I can't get working properly is instance ownership transfer
in constructor.

So classes in library are defined like follows:

class Owner {
...
}

class Data {
 Data(Owner *owner); // <-- Here happens ownership transfer.
}


Python code is like follows:

owner = Owner()
data_1 = Data(owner)
data_2 = Data(owner)

So when Python script stops runnning it causes crash due the fact that
I've data objects are automatically destroyed by Owner-class but Python
deletes them by using Data-class destructor (which shouldn't happen
ever).



If I understand you correctly then you want the owner object to remain
alive at least as long as data_1 and data_2? If so you could use
with_custodian_and_ward:

http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2/with_custodian_and_ward.html

For example something like the following should work:

 namespace py = boost::python;
 py::class_<
 ...
 > my_class(
 "Data",
 "docstring.",
 py::init< Owner * >( "Constructor." )[
 py::with_custodian_and_ward< 1, 2 >()
 ]
 );

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig





--
Jani Tiainen

- Well planned is half done, and a half done has been sufficient before...


___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig




--
Jani Tiainen

- Well planned is half done and a half done has been sufficient before...


___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig