Archived

This topic is now archived and is closed to further replies.

ulk

Python embedding

Recommended Posts

ulk    122
Python... a great language, no doubt. And the abillity to be able to extend it with C/C++ code, fantastic. But has anybody been able to successfully embed Python in their game/application to use it as a scripting language of sorts? I am in the process of writing a game and from the documentation and word of mouth gathered that Python would be just the thing for the scripting part. And sure enough it is easy enough to run Python code from C/C++. However, in order to be make it do something actually useful for my game it would be handy to be able to pass in anything besides the basic data types (strings, numerics) such as either an instance of or a pointer to a gameobject. What I want to be able to do is something like this: GameObject go; Py_Initialize() ... PyObject* po = GameObject2PyObject(go); ... result = PyObject_CallObject(func, "O", po ); ... go = PyObject2GameObject(result); Theres alot of documentation and discussion out there that suggests that this should be possible but noone seems to tell you how it''s actually done. Am I just missing something blatantly obvious? Thanks //ulk

Share this post


Link to post
Share on other sites
ulk    122
Just thought I''d update my post as I have finally figured it out after a week of trial and errors.

To pass an object "MyObject" into a Python script first create a wrapper for it using SWIG. SWIG will generate everything needed by Python to manipulate MyObject and a bunch of C code for creating, casting and manipulating these objects. It amongst other things creates a function:
PyObject* SWIG_NewPointerObj((void*)ptr, swig_type_info*, int)
This is used to create a new pointer to a structure of type swig_type_info that again points to the data pointed to by ptr. The last argument I am not to sure what is, but it works for me if I leave it as 1. To use this function you will need to have a swig_type_info* that describes your MyObject object, this is usually taken care of by SWIG as well so if you have a lot of objects in your wrapper file it is probably best to have them set up for you by making a call to the SWIG_init() function that was generated for your wrapper.
To make a long story short it can be used like this:

{
#include "you_wrapper_code_created_by_swig"

MyObject object;
PyObject *mod, *dict, *func, *result;

Py_Initialize()
SWIG_init(); //Initialise SWIG types

mod = PyImport_ImportModule( modulename );
dict = PyModule_GetDict( mod );
func = PyDict_GetItemString( dict, "testObject" );
arg = SWIG_NewPointerObj((void*)&object, SWIGTYPE_p_IObject, 1);
result = PyObject_CallFunction( func, "O", arg);

Py_Finalize();

}


and in your python script:

def testObject( o ):
object = MyObjectPtr(o) #we need to create a pointer
#from the data that gets pased in
...
#Do what ever you like with the object
...

As it''s a pointer to the actual object that gets passed to python you will not have to worry about passing it back because any changes made in python will affect the object created in C/C++, unless of course you make a copy of it on the python side.

Anyway, that''s the way I did it and I''m quite pleased with myself because noone else is willing to offer any assistance on the subject. I hope this will helo anyone who finds himself in my situation.

//ulk

Share this post


Link to post
Share on other sites