register_ptr_to_python and get_pointer
I'm trying to integrate Boost::python templates to expose a bunch of legacy classes. We have our own reference-counting pointer template, ref_ptr; the moral equivalent of shared_count. Having gotten basic classes, I set out to figure out how to to expose ref_ptr. Looking at the notes on this list and the PythonInfoWiki I figured out how to wrap my classes with shared_ptr using register_ptr_to_python. I then attempted to switch from shared_ptr to our own ref_ptr and kept getting cryptic errors like the following: boost\python\object\make_ptr_instance.hpp(31) : error C2784: 'T *boost::python::get_pointer(const boost::python::handle<T> &)' : could not deduce template argument for 'const boost::python::handle<T> &' from 'const ref_ptr<TRef>' I am not a C++ template god by any stretch of the imagination, but I was determined to try to make this work or at least understand why it wouldn't. After dissecting pointee, pointer_holder, make_instance, et al., I finally realized that my problem was that there was no get_pointer template function for class instances of my ref_ptr template. All I needed to do was the following: namespace boost { namespace python { /* Need to provide get_pointer template function for SigFoundation::ref_ptr, so that boost holder templates can use it to extract values. */ template <class T> T* get_pointer(example::ref_ptr<T> const& p) { return p.get(); } }} // namespace boost::python With this in place, I was able to get my version of the register_ptr_to_python sample working. (It's included below in toto for your reference.) I guess the question I have ism why isn't this documented anywhere? I have found boost::python to be the best library for getting at C++ stuff from python, but the terseness of the documentation and lack of examples for integrating with legacy code is frustrating. Also, if this isn't the correct way to do this, I'd be glad to know what is. Here is the register_python_to_pointer sample modified for a thirdparty ref-counting-pointer template: Thanks. === test.cpp === #include <xstring> #include <boost/python/class.hpp> #include <boost/python/module.hpp> #include <boost/python/def.hpp> #include <boost/python/call_method.hpp> #include <boost/python/register_ptr_to_python.hpp> #include <boost/python/exception_translator.hpp> #include <boost/python/overloads.hpp> #include <boost/python/pointee.hpp> #include <boost/python/converter/arg_from_python.hpp> namespace boost { namespace python { /* Need to provide get_pointer template function for example::ref_ptr, so that boost holder templates can use it to extract values. */ template <class T> T* get_pointer(example::ref_ptr<T> const& p) { return p.get(); } }} // namespace boost::python namespace example { namespace test { namespace ref_ptr { using boost::shared_ptr; using boost::is_pointer; using boost::remove_pointer; using boost::python::call_method; using boost::python::class_; using boost::python::def; using boost::python::init; using boost::python::pointee; using boost::python::register_exception_translator; using boost::python::register_ptr_to_python; using boost::python::to_python_converter; using std::wstring; class C { public: C() : str(L"hello ref_ptr") {} C(wstring const& aString) : str(aString) {} virtual ~C() {} virtual wstring GetString() const { return str; } private: wstring str; }; class Factory { public: Factory() {} CVxRefPtr< C > NewC(wstring const& aString) { return CVxRefPtr< C >(new C(aString)); } wstring frpc(CVxRefPtr< C > c) {return c->GetString();} wstring fconstc(C const& c) { return c.GetString();} wstring fc(C& c) { return c.GetString();} }; class C_Wrapper: public C { public: C_Wrapper(PyObject* self_) : C(), self(self_) {} C_Wrapper(PyObject* self_, wstring const& aString) : C(aString), self(self_) {} C_Wrapper(PyObject* self_, const C& c): self(self_), C(c) {} ~C_Wrapper() {} wstring GetString() const { return call_method<wstring>(self, "GetString"); } wstring default_GetString() const { return C::GetString(); } PyObject* self; }; BOOST_PYTHON_MODULE(test) { class_<C, C_Wrapper >("C") .def(init<wstring const&>()) .def("GetString", &C::GetString, &C_Wrapper::default_GetString); register_ptr_to_python< CVxRefPtr< C > >(); class_<Factory>("Factory") .def("NewC", &Factory::NewC) .def("frpc", &Factory::frpc) .def("fconstc", &Factory::fconstc) .def("fc", &Factory::fc); } }}} // namespace example::test::ref_ptr === test.py === from test import C, Factory f=Factory() x=f.NewC("fba") c=C("foo") f.frpc(x) # succeeds f.frpc(c) # fails f.fc(x) # succeeds f.fc(c) # succeeds f.fconstc(x) # succeeds f.fconstc(c) # succeeds -- marc.kwiatkowski@veritas.com
Marc Kwiatkowski <Marc.Kwiatkowski@veritas.com> writes:
I'm trying to integrate Boost::python templates to expose a bunch of legacy classes. We have our own reference-counting pointer template, ref_ptr; the moral equivalent of shared_count. Having gotten basic classes, I set out to figure out how to to expose ref_ptr. Looking at the notes on this list and the PythonInfoWiki I figured out how to wrap my classes with shared_ptr using register_ptr_to_python. I then attempted to switch from shared_ptr to our own ref_ptr and kept getting cryptic errors like the following:
boost\python\object\make_ptr_instance.hpp(31) : error C2784: 'T *boost::python::get_pointer(const boost::python::handle<T> &)' : could not deduce template argument for 'const boost::python::handle<T> &' from 'const ref_ptr<TRef>'
I am not a C++ template god by any stretch of the imagination, but I was determined to try to make this work or at least understand why it wouldn't. After dissecting pointee, pointer_holder, make_instance, et al.
The documentation you need is in the CVS at: http://tinyurl.com/ytef5 Unfortunately, register_ptr_to_python doesn't document the Dereferenceable requirement :( Will fix immediately.
, I finally realized that my problem was that there was no get_pointer template function for class instances of my ref_ptr template. All I needed to do was the following:
namespace boost { namespace python {
/* Need to provide get_pointer template function for SigFoundation::ref_ptr, so that boost holder templates can use it to extract values. */
template <class T> T* get_pointer(example::ref_ptr<T> const& p) { return p.get(); } }} // namespace boost::python
This is right if you're using a compiler with broken Argument-Dependent Lookup such as msvc6 or 7. VC7.1 supports ADL so get_pointer should go in the "example" namespace. I suggest using #ifdefs to ensure that your code will still work when you move to a working compiler.
With this in place, I was able to get my version of the register_ptr_to_python sample working. (It's included below in toto for your reference.)
I guess the question I have ism why isn't this documented anywhere?
Pure oversight, sorry.
I have found boost::python to be the best library for getting at C++ stuff from python, but the terseness of the documentation
We'd love to have more time to spend on making the docs friendlier. Patches are welcome.
and lack of examples for integrating with legacy code
I'm not sure what this means. Are you referring to, for example, the fact that register_ptr_to_python doesn't show how to work with random smart pointers? I can understand that, if so. Do you have any other examples?
is frustrating. Also, if this isn't the correct way to do this, I'd be glad to know what is.
Here is the register_python_to_pointer sample modified for a thirdparty ref-counting-pointer template:
Wonderful! Do you intend to contribute this to the documentation base, and will you agree to have it distributed under the terms of the Boost Software License 1.0 (http://www.boost-consulting.com/boost/LICENSE_1_0.txt)? -- Dave Abrahams Boost Consulting www.boost-consulting.com
Thanks for your reply. With respect to the documentation, I think the biggest simple thing we could do to improve things is to add a keyword and concept index, along the lines of David Abrahams writes:
Marc Kwiatkowski <Marc.Kwiatkowski@veritas.com> writes:
I'm trying to integrate Boost::python templates to expose a bunch of legacy classes. We have our own reference-counting pointer template, ref_ptr; the moral equivalent of shared_count. Having gotten basic classes, I set out to figure out how to to expose ref_ptr. Looking at the notes on this list and the PythonInfoWiki I figured out how to wrap my classes with shared_ptr using register_ptr_to_python. I then attempted to switch from shared_ptr to our own ref_ptr and kept getting cryptic errors like the following:
boost\python\object\make_ptr_instance.hpp(31) : error C2784: 'T *boost::python::get_pointer(const boost::python::handle<T> &)' : could not deduce template argument for 'const boost::python::handle<T> &' from 'const ref_ptr<TRef>'
I am not a C++ template god by any stretch of the imagination, but I was determined to try to make this work or at least understand why it wouldn't. After dissecting pointee, pointer_holder, make_instance, et al.
The documentation you need is in the CVS at:
Unfortunately, register_ptr_to_python doesn't document the Dereferenceable requirement :(
Will fix immediately.
, I finally realized that my problem was that there was no get_pointer template function for class instances of my ref_ptr template. All I needed to do was the following:
namespace boost { namespace python {
/* Need to provide get_pointer template function for SigFoundation::ref_ptr, so that boost holder templates can use it to extract values. */
template <class T> T* get_pointer(example::ref_ptr<T> const& p) { return p.get(); } }} // namespace boost::python
This is right if you're using a compiler with broken Argument-Dependent Lookup such as msvc6 or 7. VC7.1 supports ADL so get_pointer should go in the "example" namespace. I suggest using #ifdefs to ensure that your code will still work when you move to a working compiler.
With this in place, I was able to get my version of the register_ptr_to_python sample working. (It's included below in toto for your reference.)
I guess the question I have ism why isn't this documented anywhere?
Pure oversight, sorry.
I have found boost::python to be the best library for getting at C++ stuff from python, but the terseness of the documentation
We'd love to have more time to spend on making the docs friendlier. Patches are welcome.
and lack of examples for integrating with legacy code
I'm not sure what this means. Are you referring to, for example, the fact that register_ptr_to_python doesn't show how to work with random smart pointers? I can understand that, if so. Do you have any other examples?
is frustrating. Also, if this isn't the correct way to do this, I'd be glad to know what is.
Here is the register_python_to_pointer sample modified for a thirdparty ref-counting-pointer template:
Wonderful! Do you intend to contribute this to the documentation base, and will you agree to have it distributed under the terms of the Boost Software License 1.0 (http://www.boost-consulting.com/boost/LICENSE_1_0.txt)?
-- Dave Abrahams Boost Consulting www.boost-consulting.com
_______________________________________________ C++-sig mailing list C++-sig@python.org http://mail.python.org/mailman/listinfo/c++-sig
Marc Kwiatkowski <Marc.Kwiatkowski@veritas.com> writes:
Thanks for your reply. With respect to the documentation, I think the biggest simple thing we could do to improve things is to add a keyword and concept index, along the lines of
... ??? -- Dave Abrahams Boost Consulting www.boost-consulting.com
(sorry for the first one, mis-fired) Thanks for your reply. With respect to the documentation, I think the biggest simple thing we could do to improve things is to add a keyword and concept index, along the lines of the python library and language index. Searching for get_pointer from boost.org's search form does not point to the refence documentation you included below, nor does the Reference TOC. You kind of have to know it's there to find it. Secondly, now that I've seen it it still isn't clear to me that it's a template the application developer is meant to extend. They best thing for would be more comprehensive, real-world examples, particularly those emphasing integration the legacy code. Given that they don't really exist, I'll just report problems I have and submit whatever sample code I can to this list with the hope that others can benefit from it. Regarding the register_python_to_pointer sample, I will be happy to submit it.
Marc Kwiatkowski <Marc.Kwiatkowski@veritas.com> writes:
I'm trying to integrate Boost::python templates to expose a bunch of legacy classes. We have our own reference-counting pointer template, ref_ptr; the moral equivalent of shared_count. Having gotten basic classes, I set out to figure out how to to expose ref_ptr. Looking at the notes on this list and the PythonInfoWiki I figured out how to wrap my classes with shared_ptr using register_ptr_to_python. I then attempted to switch from shared_ptr to our own ref_ptr and kept getting cryptic errors like the following:
boost\python\object\make_ptr_instance.hpp(31) : error C2784: 'T *boost::python::get_pointer(const boost::python::handle<T> &)' : could not deduce template argument for 'const boost::python::handle<T> &' from 'const ref_ptr<TRef>'
I am not a C++ template god by any stretch of the imagination, but I was determined to try to make this work or at least understand why it wouldn't. After dissecting pointee, pointer_holder, make_instance, et al.
The documentation you need is in the CVS at:
Unfortunately, register_ptr_to_python doesn't document the Dereferenceable requirement :(
Will fix immediately.
, I finally realized that my problem was that there was no get_pointer template function for class instances of my ref_ptr template. All I needed to do was the following:
namespace boost { namespace python {
/* Need to provide get_pointer template function for SigFoundation::ref_ptr, so that boost holder templates can use it to extract values. */
template <class T> T* get_pointer(example::ref_ptr<T> const& p) { return p.get(); } }} // namespace boost::python
This is right if you're using a compiler with broken Argument-Dependent Lookup such as msvc6 or 7. VC7.1 supports ADL so get_pointer should go in the "example" namespace. I suggest using #ifdefs to ensure that your code will still work when you move to a working compiler.
With this in place, I was able to get my version of the register_ptr_to_python sample working. (It's included below in toto for your reference.)
I guess the question I have ism why isn't this documented anywhere?
Pure oversight, sorry.
I have found boost::python to be the best library for getting at C++ stuff from python, but the terseness of the documentation
We'd love to have more time to spend on making the docs friendlier. Patches are welcome.
and lack of examples for integrating with legacy code
I'm not sure what this means. Are you referring to, for example, the fact that register_ptr_to_python doesn't show how to work with random smart pointers? I can understand that, if so. Do you have any other examples?
is frustrating. Also, if this isn't the correct way to do this, I'd be glad to know what is.
Here is the register_python_to_pointer sample modified for a thirdparty ref-counting-pointer template:
Wonderful! Do you intend to contribute this to the documentation base, and will you agree to have it distributed under the terms of the Boost Software License 1.0 (http://www.boost-consulting.com/boost/LICENSE_1_0.txt)?
-- Dave Abrahams Boost Consulting www.boost-consulting.com
_______________________________________________ C++-sig mailing list C++-sig@python.org http://mail.python.org/mailman/listinfo/c++-sig
-- marc.kwiatkowski@veritas.com
Marc Kwiatkowski <Marc.Kwiatkowski@veritas.com> writes: F> (sorry for the first one, mis-fired)
Thanks for your reply. With respect to the documentation, I think the biggest simple thing we could do to improve things is to add a keyword and concept index, along the lines of the python library and language index. Searching for get_pointer from boost.org's search form does not point to the refence documentation you included below, nor does the Reference TOC. You kind of have to know it's there to find it.
Yeah, but that's just because it's only in the CVS documentation and boost.org's search form only indexes the released Boost site.
Secondly, now that I've seen it it still isn't clear to me that it's a template the application developer is meant to extend. They best thing for would be more comprehensive, real-world examples, particularly those emphasing integration the legacy code. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You haven't confirmed/denied my understanding of your meaning
Given that they don't really exist, I'll just report problems I have and submit whatever sample code I can to this list with the hope that others can benefit from it. Regarding the register_python_to_pointer sample, I will be happy to submit it.
I await your submission. At that time, please answer the following:
will you agree to have it distributed under the terms of the Boost Software License 1.0 (http://www.boost-consulting.com/boost/LICENSE_1_0.txt)?
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Yet another question/observation about register_ptr_to_python. Given a function that returns a ref-ptr, it seems that all that is really necessary is to provide a get_pointer template function for it and then invoke the register_to_python function. None of the wrapper stuff is necessary. For example: class X { public: X(wstring const& aValue) : value(aValue) {} wstring value; }; my_ref_ptr<X> NewX(wstring const& aValue ) { return my_ref_ptr<X>(new X(aValue)); } namespace boost { namespace python { template <class T> T* get_pointer(my_ref_ptr<T> const& p) { return p.get(); } }} BOOST_PYTHON_MODULE(test) { class_<X>("X", init<wstring const&>()) .def_readwrite("value", &X::value); def("NewX", &NewX); register_ptr_to_python< my_ref_ptr< X > >(); } That's all there is too it. This seems so much more straight forward than the sample described in libs/python/doc/v2/register_ptr_to_python.html On the other hand, when I used ref-ptrs with a mix of derived and base classes, I can find no permutation of wrapper and smart pointer that will work to get at a base method from a derived object ptr that is downcast to a base object pointer. For example, given the Base, Derived, and Factory classes attached below, the following script fails
from pytest import Base, Factory, Derived;f=Factory() d=f.NewDerived("i am derived") d.GetString() u'i am derived' b=f.Downcast(d) b.GetString() Traceback (most recent call last): File "<stdin>", line 1, in ? Boost.Python.ArgumentError: Python argument types in Derived.GetString(Derived) did not match C++ signature: GetString(class Filer::Test::Example::PyDerivedWrapper {lvalue}) GetString(class Filer::Test::Example::PyDerived {lvalue})
using boost::shared_ptr; using boost::python::call_method; using boost::python::class_; using boost::python::def; using boost::python::init; using boost::python::register_ptr_to_python; using std::wstring; /* get_pointer template function for my_ref_ptr */ namespace boost { namespace python { template <class T> T* get_pointer(my_ref_ptr<T> const& p) { return p.get(); } }} // Base class class PyBase { public: PyBase() {} PyBase(wstring const& aString) : str(aString) {} virtual ~PyBase() {} wstring GetString() {return str;} wstring str; }; // Derived class class PyDerived : public PyBase { public: PyDerived() {} PyDerived(wstring const& aString) : PyBase(aString) {} virtual ~PyDerived() {}; void SetString(wstring const& aValue) { str = aValue; } }; // Factory to make Base and Derived classes and downcast latter to former class Factory { public: Factory() {} my_ref_ptr< PyBase > NewBase(wstring const& aString) { return my_ref_ptr< PyBase >(new PyBase(aString)); } my_ref_ptr< PyDerived > NewDerived(wstring const& aString) { return my_ref_ptr< PyDerived >(new PyDerived(aString)); } my_ref_ptr< PyBase > Downcast(my_ref_ptr< PyDerived > aDerived) { return my_ref_ptr< PyBase >(aDerived.get()); } }; // BaseWrapper...what does this do? class PyBaseWrapper: public PyBase { public: PyBaseWrapper(PyObject* self_): self(self_) {} PyBaseWrapper(PyObject* self_, const PyBase& c): self(self_), PyBase(c) {} PyBaseWrapper(PyObject* self_, wstring const& aString) : self(self_), PyBase(aString) {} wstring GetString() {return call_method<wstring>(self, "GetString");} wstring default_GetString() {return PyBase::GetString();} PyObject* self; }; // DerivedWrapper... class PyDerivedWrapper: public PyDerived { public: PyDerivedWrapper(PyObject* self_): self(self_) {} PyDerivedWrapper(PyObject* self_, const PyDerived& c): self(self_), PyDerived(c) {} PyDerivedWrapper(PyObject* self_, wstring const& aString) : self(self_), PyDerived(aString) {} wstring GetString() {return call_method<wstring>(self, "GetString");} wstring default_GetString() {return PyDerived::GetString();} PyObject* self; }; BOOST_PYTHON_MODULE(test) { class_< PyBase >("Base") .def(init<wstring const&>()) .def("GetString", &PyBase::GetString, &PyBaseWrapper::default_GetString) .def_readwrite("str", &PyBase::str); register_ptr_to_python< my_ref_ptr< PyBase > >(); class_< PyDerived, PyDerivedWrapper >("Derived") .def(init<wstring const&>()) .def("GetString", &PyDerived::GetString, &PyDerivedWrapper::default_GetString) .def("SetString", &PyDerived::SetString) register_ptr_to_python< my_ref_ptr< PyDerived > >(); class_<Factory>("Factory") .def("NewBase", &Factory::NewBase) .def("NewDerived", &Factory::NewDerived) .def("Downcast", &Factory::Downcast); } -- marc.kwiatkowski@veritas.com
Marc Kwiatkowski <Marc.Kwiatkowski@veritas.com> writes:
Yet another question/observation about register_ptr_to_python.
Given a function that returns a ref-ptr, it seems that all that is really necessary is to provide a get_pointer template function for it and then invoke the register_to_python function.
That's right.
None of the wrapper stuff is necessary.
What "wrapper stuff"? Do you mean A_wrapper in the example in the docs?
For example:
class X { public: X(wstring const& aValue) : value(aValue) {} wstring value; };
my_ref_ptr<X> NewX(wstring const& aValue ) { return my_ref_ptr<X>(new X(aValue)); }
namespace boost { namespace python {
template <class T> T* get_pointer(my_ref_ptr<T> const& p) { return p.get(); } }}
BOOST_PYTHON_MODULE(test) {
class_<X>("X", init<wstring const&>()) .def_readwrite("value", &X::value);
def("NewX", &NewX);
register_ptr_to_python< my_ref_ptr< X > >(); }
That's all there is too it. This seems so much more straight forward than the sample described in libs/python/doc/v2/register_ptr_to_python.html
It illustrates something different from your code.
On the other hand, when I used ref-ptrs with a mix of derived and base classes, I can find no permutation of wrapper and smart pointer that will work to get at a base method from a derived object ptr that is downcast to a base object pointer.
That's an upcast.
For example, given the Base, Derived, and Factory classes attached below, the following script fails
from pytest import Base, Factory, Derived;f=Factory() d=f.NewDerived("i am derived") d.GetString() u'i am derived' b=f.Downcast(d) b.GetString() Traceback (most recent call last): File "<stdin>", line 1, in ? Boost.Python.ArgumentError: Python argument types in Derived.GetString(Derived) did not match C++ signature: GetString(class Filer::Test::Example::PyDerivedWrapper {lvalue}) GetString(class Filer::Test::Example::PyDerived {lvalue})
Well, you didn't include enough information to make this problem reproducible (a definition of my_ref_ptr is missing, and I don't know what else), so there's only so much I can do to help.
From this part of the error message
Derived.GetString(Derived) it's clear that b is actually a Python Derived object, not a Base object as one would expect (try doing print type(b)). It seems like there's something very wrong here, and the only explanation I can come up with is that my_ref_ptr<Base>::element_type is Derived. See http://www.boost-consulting.com/boost/libs/python/doc/v2/pointee.html. The other thing that looks suspicious is that you haven't declared an inheritance relationship between Base and Derived using bases<...>. There'd be no need to expose GetString again in Derived if you did that. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com
Hello, I have used boost::python to make python bindings for a rather large interface at work. There, we have lots of virtual interfaces, with python using and invoking them, and in a few cases, extending them, with no problem. Now, at home, I am trying to bind another project. This one is a bit different. The root of the problem is that I want python's "held values" for my types to usually be pointers. The project I am binding with makes heavy use of pointer identity (for serializing structs for network comm.) I am running into some problems. Basically, I am calling a python function with structure instances... like so: PyObject* func; foo* foo_instance; boost::python::call<void>(func, foo_instance); But, binding foo is problematic... If I use: class_<foo>("foo")...;, then copies of foo instances are made, and used in the python objects, even though I am calling functions and passing in foo* parameters. If I use: class_<foo, boost::noncopyable>("foo")...;, then when I pass in my foo* values, I get boost python errors (when I call the function), "no to-python (by-value) convertor for struct foo"... If I wrap my foo*'s in a simple template "smart pointer" class I made, and use: class_<foo, simple_wrap<foo>, boost::noncopyable>("foo")...;, then the object identity works fine, but it still complains about "no to-python" convertors if I use raw foo*'s in boost::python::call instead of explicitly wrapping them in simple_wrap<foo>... I would have thought this pattern at least somewhat common... For return values, you can specify reference_existing_object, return_opaque_pointer, etc... How do we do this for input values?
"Dusty Leary" <dleary@ttlc.net> writes:
Hello,
I have used boost::python to make python bindings for a rather large interface at work. There, we have lots of virtual interfaces, with python using and invoking them, and in a few cases, extending them, with no problem.
Now, at home, I am trying to bind another project. This one is a bit different.
The root of the problem is that I want python's "held values" for my types to usually be pointers. The project I am binding with makes heavy use of pointer identity (for serializing structs for network comm.)
I am running into some problems.
Basically, I am calling a python function with structure instances... like so:
PyObject* func; foo* foo_instance; boost::python::call<void>(func, foo_instance);
But, binding foo is problematic...
If I use: class_<foo>("foo")...;, then copies of foo instances are made, and used in the python objects, even though I am calling functions and passing in foo* parameters.
If I use: class_<foo, boost::noncopyable>("foo")...;, then when I pass in my foo* values, I get boost python errors (when I call the function), "no to-python (by-value) convertor for struct foo"...
Pass ptr(x) instead of x if you don't want the foo copied. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com
Pass ptr(x) instead of x if you don't want the foo copied.
Thanks very much. Is there a way to specify this as the default behavior for a type, maybe via the to_python handlers or whatever? Basically, something so that whenever I call python with a foo*, it will do the pointer_wrapper<> thing...
"Dusty Leary" <dleary@ttlc.net> writes:
Pass ptr(x) instead of x if you don't want the foo copied.
Thanks very much.
Is there a way to specify this as the default behavior for a type, maybe via the to_python handlers or whatever?
Nope.
Basically, something so that whenever I call python with a foo*, it will do the pointer_wrapper<> thing...
Sorry, it's explicit for a reason: passing by-raw-pointer is unsafe. The original C++ object's lifetime can end while the Python object is still alive, and usage of the Python object thereafter can crash the interpreter. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (3)
-
David Abrahams -
Dusty Leary -
Marc Kwiatkowski