Extending Python with C++ singleton pattern using boost python lib

Jörg Sauer joerg2k1 at yahoo.de
Mon Apr 23 03:22:39 EDT 2001


Hi folks,
I've got the following problem exposing a c++ singleton pattern to
python.

I implemented the singleton class as shown below. I want to make it a
hook for my Application, which will embed python, to register objects
in order to access them in python scripts.

The singleton class has to methods to register objects setObject() and
getObject().The common c++ function getReg() will call the singletons
static Init function and retrieve a reference to it.

Everything compiles fine without any warnings. (Windows 2000SP1,
Python 2.0, Boost Python 1.21.1, VC6.0SP4)

When I run the following script:
>>> import getting_started1
>>> reg1 = getting_started1.GetReg()
CobRegistry constructor
Address: 007c96e8
>>> reg2 = getting_started1.GetReg()
Address: 007c96e8
>>> reg1
<CObRegistry object at 007a0f88>
>>> reg2
<CobRegistry object at 007c9a60>
>>> reg1.setObject(50)
>>> reg1.getObject()
50
>>> reg2.getObject()
7899920
>>> reg2.setObject(10)
>>> reg2.getObject()
10

When I include a cout << this statement in the getObject method I get
reg1 address (c++): 07aaaec
reg1 address (c++): 07aa80c

What is going wrong???

It seems that the python c++ wrapper instantiate 2 different singleton
objects. The static member keeps constant and the constructor is
called only one time, but how can I get two singleton objects then?

What I want to get is that every call to GetReg() gets the same c++
object and that python calls like reg1.setObject(40);
reg2.setObject(10); change the same c++ memory thow it doesn't matter
through which. Python object I store or retrieve date.

Any suggestions?
Thanks a lot
Joerg
------ Sample Code ----------


#include <iostream>
#include <string>
using std::cout;
using std::endl;


#include <boost/python/class_builder.hpp>
namespace python = boost::python;


namespace mein{ // Avoid cluttering the global namespace.

class CObRegistry  // Singleton class 
{
// Singleton 
private:
	static CObRegistry* m_pObRegistry;	protected:
	CObRegistry();	
public:
	static CObRegistry& Init()
	CObRegistry& GetReg();
// My functions
protected:
	int	m_TestObj;
public:
	int getObject();
	void setObject(int);
};

CObRegistry* CObRegistry::m_pObRegistry = 0;	


CObRegistry::CObRegistry()
{
	cout << "CObRegistry construktor" << endl;
}

CObRegistry& CObRegistry::Init()
{
	if(m_pObRegistry==0)
		m_pObRegistry = new CObRegistry;
	cout << "Addresse: " << m_pObRegistry << endl;
	return *m_pObRegistry;
}

CObRegistry& CObRegistry::GetReg()
{
	return Init();
}


int CObRegistry::getObject()
{
	return m_TestObj;
}

void CObRegistry::setObject(int x)
{
	m_TestObj = x;
}

CObRegistry& GetReg()
{
	return CObRegistry::Init();
}

}
using namespace mein;

#include <boost/python/class_builder.hpp>
namespace python = boost::python;

// Python requires an exported function called init<module-name> in
every
// extension module. This is where we build the module contents.
extern "C"
#ifdef _WIN32
__declspec(dllexport)
#endif
initgetting_started1()
{
  try
  {
    // Create an object representing this extension module.
    python::module_builder this_module("getting_started1");

    // Create the Python type object for our extension class.
    python::class_builder<CObRegistry> CObRegistry_class(this_module,
"ObRegistry");


//Add the __init_-function
// I commented this out but that doesn't change anything, so you can
uncomment it
//    CObRegistry_class.def(python::constructor< >());// brackets <>
are necessary


//Add memberfunctions of myObj_class,singleton_class
	CObRegistry_class.def(&CObRegistry::getObject, "getObject");
	CObRegistry_class.def(&CObRegistry::setObject, "setObject");
	CObRegistry_class.def(&CObRegistry::Init, "Init");

//Add normal function
	this_module.def(GetReg,"GetReg");

  }
  catch(...)
  {
    python::handle_exception(); // Deal with the exception for Python
  }
}





More information about the Python-list mailing list