[C++-sig] Accessing instances of C++ objects in Python - Plus more

Mike Gonzales mgonzale at digipen.edu
Thu Apr 1 22:20:40 CEST 2004


Sorry if I am asking a question that has already been answered; the number
of threads in this forum is formidable, and I can only see so far.  This
question was asking previously by my teammate Adrian Bentley; now that we
know more about the problem, hopefully we can get an answer ;).

I am working on a game engine that is attempting to use python for
scripting support.  And unusual requirement of our engine is the necessity
of be able to manipulate types in C++ or Python, pretty much at the same
time, e.g. dynamically  instantiating an entity in C++ and then being able
to manipulate it in python, and then updating its status in C++.  I won't
go into detail on why this is necessary, suffice to say, it has to deal
with managing modules at run-time.

I am most of the way to acheiving this goal; however, I am having trouble
trying to access said C++ objects from python after I have instantiated them.

to give you some idea what I am trying to do, following the boost tutorial
I have a class that looks sorta like this

---------------------------------------------------
struct PythonManager
{
	dict main_namespace;
	handle<> main_module;

 //calls PyInitialize, and grabs the main module and namespace
	PythonManager();

 //calls PyFinalize
	~PythonManager();

 //runs the interpreter on a single expression, and returns the result
	object EvaluateExpression(std::string &exp);
 //runs the interpreter on a multiline script
	void EvaluateScript(std::string &scr);

	struct PythonWrapper: public PyObject
	{};
 	
	PythonWrapper * MakeDualObject(int sizebytes, PyTypeObject *pto,
			std::string &varname)
	{
		//Get memory from Python and do necessary Python initialization
		PythonWrapper * mem = (PythonWrapper*)PyObject_Malloc(sizebytes);
		object obj( handle<>(PyObject_Init(mem, pto)));

		//put the variable into Python's variable namespace
		main_namespace[varname.c_str()] = obj;
		
		//set up some of my own tracking here....

		return mem;
	}
};
-----------------------------------------------------------

Now, the test that I am subjecting myself to see if all of this works is to
have one of my defined types that I have extended into Python and another
that I have created behind the scenes (like above) play well together.
Unfortunately, I haven't gotten that far; so far, I am having trouble
trying to get Python to recognize the types that I have just fed it.

I successfully have extended a quaternion class in to python, and so I am
using that as my test case, even stealing its typeobj * for use in the
making these dual-language-objects.

------------------------------------------------------
struct PyQuat: public PyWrapper, public quat
{};

//...
_PythonManager.EvaluateScript("import mymath");
_PythonManager.EvaluateScript("x = mymath.quat(1,0,0,0)");
object testquat = _PythonManager.EvaluateExpression("x");

//verify that testquat really is a quat.

PyWrapper *test = _PythonManager.MakeDualObject(sizeof(PyQuat), 
						testquat.ptr()->objtype, "y");
//now the interpreter goes "boom!"
_PythonManager.EvaluateScript("printquat(y)");
--------------------------------------------------------------

So, obviously what I am doing here is probably sub-optimal; still does
anybody know of how to pull this off?  Even better, if anybody knows of a
more elegant way to pull this off, I am all ears.  And again, once I pull
that off above, I'll need to be able to make a behind-the-scenes-quat and
made-in-python-quat play nicely; any advice on how to make that work would
be really appreciated.

Thanks for your time and patience,
Mike Gonzales





More information about the Cplusplus-sig mailing list