[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