[C++-sig] Re: creating an instance of a class_<> object in c++ and exporting it to python

Francois Ostiguy ostiguy at fnal.gov
Mon Aug 16 23:51:17 CEST 2004


>
> As Mike and I wrote, just do this:
>
>   object PythonInstanceOfA  = py_get_existing();
>

Unfortunately, that does not seem to do quite what I want.
I constructed a simple complete toy example to demonstrate.

Note the following:

(1) creating python_object_a forces an undesired instantiation of
    a type A (i.e. in addition to the the existing instance a)

(2) if the interface defines a python object without
     an __init__ function, the result is a runtime error:
     "Object cannot by created from python."

(3) if you compile the example, here is what you get when the
    module is imported from python


  Python 2.3.3 (#1, Jul  7 2004, 13:43:38)
  [GCC 3.3.3] on linux2
  Type "help", "copyright", "credits" or "license" for more information.
  >>> from inject import *
  >>> a
  <inject.A object at 0xb733b10c>
  >>> dir()
  ['A', '__builtins__', '__doc__', '__name__', 'a']
  >>> dir (a)
  ['A', '__class__', '__delattr__', '__dict__', '__doc__',
  '__getattribute__', '__hash__', '__init__', '__instance_size__',
  '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
  '__setattr__', '__str__', '__weakref__']
  >>>

  Note that the object instance "a" has been injected. However, for a
  reason that escapes me, the method "dummy" which is
  part of the specified interface is not correctly exported.

  Again, my goal is to wrap an existing instance of A, without
  having to create a spurious object (basically without having to
  call the A constructor more than once).

  Comments, suggestions ???

-Francois

----------------------------------------------------------------------------
Dr. Jean-Francois OSTIGUY                              voice: (630) 840-2231
Beam Physics Dept MS220                                  FAX: (630) 840-6039
Fermi National Accelerator Laboratory                email: ostiguy at fnal.gov
Batavia IL 60510-0500                           WWW:www-ap.fnal.gov/~ostiguy


/////// *************** example: inject.cpp **************** /////////

#include <boost/python.hpp>

class A {
public:
  A(int d) { _dummy = d; }
  int dummy() { return _dummy;}
private:

  int _dummy;
};

A* a = 0;

A* get_existing() { return a; }

void inject_object();

using namespace boost::python;

class_ <A, A*,  boost::noncopyable>* PythonTypeAPtr;

BOOST_PYTHON_MODULE( inject )
{


    static class_ <A, A*,  boost::noncopyable> PythonTypeA("A", init<int>());

   //*** note: using no_init here will cause a runtime error !!

   PythonTypeA.def("A", &A::dummy);

   /***** this does not seem to export the dummy function to python. Why ?

   PythonTypeAPtr = &PythonTypeA;

    inject_object();

}

void  inject_object() {

 a = new A(99);

 object py_get_existing =
     make_function( &get_existing, return_value_policy<
reference_existing_object>() );

 object python_object_a = (*PythonTypeAPtr)(2); // <<<<<<==========
 //****** instantiation of a spurious object

 python_object_a = py_get_existing();


 handle<> main_module ( boost::python::borrowed(
PyImport_AddModule("__main__") )  );
 handle<> main_dict   ( boost::python::borrowed(
PyModule_GetDict(main_module.get()) ));
 PyDict_SetItemString  ( main_dict.get(), "a",  python_object_a.ptr() );

}




More information about the Cplusplus-sig mailing list