[C++-sig] Re: passing a dynamic PyObject * from C++ to Python
F. Oliver Gathmann
gathmann at cenix-bioscience.com
Thu Jun 26 14:20:55 CEST 2003
David Abrahams wrote:
>"F. Oliver Gathmann" <gathmann at cenix-bioscience.com> writes:
>
>
>
>> template <class T> T identity(T x) { return x; } template <class
>> T> object get_pointer_reference(T x) { object f =
>> make_function(&identity<T>,
>> return_value_policy<manage_new_object>()
>> ); return f(x); }
>>
>>
>
>Hmm, *nasty* formatting!
>
>
Strange - the formatting looks fine in the c++-SIG archives...
> template <class T>
> T identity(T x) {
> return x;
> }
>
> template <class T>
> object get_pointer_reference(T x)
> {
> object f = make_function(
> &identity<T>, return_value_policy<manage_new_object>());
>
> return f(x);
> }
>
>Hmm, looks OK to me.
>
>
>
>>which compiles fine but crashes at runtime (using gcc 3.2.2 on Linux
>>with a recent CVS version of Boost). Any hints that might help me
>>solving this mystery would be much appreciated!
>>
>>
>
>Any hints about the condition of the program at the time of crash
>would be a big help in helping you. A reproducible test case would
>be even better.
>
Sorry; I thought my error was so obvious that pseudocode would be enough
to find out what's wrong. Here is a complete test case:
#include <memory>
#include <boost/python.hpp>
using namespace boost::python;
template <class T>
T identity(T x)
{
return x;
}
template <class T>
object get_pointer_reference(T x)
{
object f = make_function(&identity<T>,
return_value_policy<manage_new_object>()
);
return f(x);
}
struct Foo {};
struct Bar {};
object readFooOrBar(bool fooOrBar)
{
if (fooOrBar)
{
Foo * fooPtr = new Foo();
return get_pointer_reference(fooPtr);
}
else
{
Bar * barPtr = new Bar();
return get_pointer_reference(barPtr);
}
}
BOOST_PYTHON_MODULE(_problem)
{
class_<Foo, std::auto_ptr<Foo> >("Foo", no_init)
;
class_<Bar, std::auto_ptr<Bar> >("Bar", no_init)
;
def("read", &readFooOrBar);
}
And in Python:
Python 2.2.2 (#1, Apr 10 2003, 23:02:08)
[GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from _problem import *
>>> foo = read(1)
>>> bar = read(0)
>>> del foo
>>> del bar
Segmentation fault
When using Nicodemus' register_ptr_to_python template like so
BOOST_PYTHON_MODULE(_problem)
{
class_<Foo>("Foo", no_init)
;
register_ptr_to_python<std::auto_ptr<Foo> >();
class_<Bar>("Bar", no_init)
;
register_ptr_to_python<std::auto_ptr<Bar> >();
def("read", &readFooOrBar);
}
the situation is essentially unchanged.
BTW, I had to insert a typename directive for gcc to compile
the register_ptr_to_python template:
namespace boost { namespace python {
template <class P>
void register_ptr_to_python(P* = 0)
{
typedef typename boost::python::pointee<P>::type X;
^------^
objects::class_value_wrapper<
P
, objects::make_ptr_instance<
X
, objects::pointer_holder<P,X>
>
>();
}
}} // namespace boost::python
I guess I am still somewhat at a loss here... - but I am certainly
learning a lot ;-)
Oliver
--------------------------------------------------------------------
F. Oliver Gathmann, Ph.D.
Director IT Unit
Cenix BioScience GmbH
Pfotenhauer Strasse 108 phone: +49 (351) 210-2735
D-01307 Dresden, Germany fax: +49 (351) 210-1309
fingerprint: 8E0E 9A64 A07E 0D1A D302 34C2 421A AE9F 4E13 A009
public key: http://www.cenix-bioscience.com/public_keys/gathmann.gpg
--------------------------------------------------------------------
More information about the Cplusplus-sig
mailing list