scripting ii/iii references:
Post on 31-Dec-2015
222 Views
Preview:
TRANSCRIPT
SCRIPTING II/III
References: • https://docs.python.org/3.4/c-api/• https://docs.python.org/3.4/extending/index.html#extendin
g-index
COMPARISON OF PART I & II
• Part I (Lab7): Python extending• Make a new dll (pyd) file from C code which is callable by
the python interpreter
EXTENDING
IDLE (or other python interpreter)
Python code (.py)
C/C++ extension (a .pyd file). Can contain:• Python interfaces to C
"classes"• Python interfaces to C
functions• Python interfaces to C
variables
COMPARISON OF PART I & II, CONT.
• Part II (Lab14): Python embedding• We'll create a light-weight python interpreter inside our
application• No IDLE, PyScripter, PyCharm this time.
• We'll have two forms of communication between C/Python:• I. C++ code will call python functions upon "events"
• Two objects colliding• A sound ending• An update function• …
• II. python functions can call C++ utility functions• LogMessage• createGameObject• …
EMBEDDING THE INTERPRETER
C/C++ Program (.exe)
Python Interpreter
Python code (strings, read from
files)
Python (.py) files
Other C/C++ objects
GENERAL APPROACH
• Create a “ssuge” module (just as before)• Includes any built-in classes and functions• GameObject class (to be expanded in part III)
• Will use a “C capsule”• We’ll maintain a global python dictionary of all of the active GO’s.
• logMessage function• createGameObject function
• Append it to the built-in modules
• Create the interpreter (one line!)• Scan for .py files and execute them• …• Shutdown the interpreter on C++ application
shutdown.
C FUNCTION POINTERS
float foo(int x, char * y) { }float foo2(int p, char * q) { }
int main(){ float (*func_ptr)(int x, char* y); // func.ptr. Var. float f;
func_ptr = &foo; f = func_ptr(7, "test");
func_ptr = &foo2; F = func_ptr(99, “blah”);}
CREATING THE EMBEDDED INTERPRETER
• "Import" the C module into the embedded interpreter:PyImport_AppendInittab(char * modName, PyObject * (*funcPtr)(void));
• Second, start up the interpreterPy_Initialize()• Note: this interpreter will (only) have modules defined with
PyImport_AppendInittab.• To add other modules…[design decision]• [lightweight]: only light-weight built-in python functionality• [heavy-weight]: put all python .pyd files in your $bin/$(Config)/
directory.
• Third, run the rest of the program• At appropriate times, load and run .py files into the embedded
interpreter (more on this shortly)
• Finally, shut down the interpreterPy_Finalize()
LOADING / EXECUTING A .PY FILE
• Load the file into a char * buffer• FILE* or fstream and new / delete
• Compile the buffer into a code modulePyObject * Py_CompileString(char * buff, char * fname, Py_file_input)• Import and Execute the code modulePyImport_ExecCodeModule(char * name, PyObject * codeMod);
• This will run the python code.• If that code references the C functions / classes with
Python interfaces, that code will now be run.• This will usually interact with the rest of the C structures in
the program
CREATING PYTHON OBJECTS IN C
• Create a tuple to pass arguments• PyTuple_New• PyTuple_SetItem
• “Call” the class (e.g. we have “PyTypeObject” struct called FooType and a C structcalled Foo)Foo * f = (Foo*)PyObject_CallObject((PyObject*)&FooType, args_tuple)
C CAPSULES
• When making our python “wrapper” around C++ GameObjects, we need to connect them.
• A C-capsule is a PyObject that just contains a void*• It’s not usable in python. • Useful to store upon creation and use later.PyObject* c = PyCapsule_New(void*, char*name, NULL);
Void* PyCapsule_GetPointer(PyObject*, char*name);
bool PyCapsue_CheckExact(PyObject *);
C EXTERN’S
• Normally we put all “stuff” we want to share in a .h• However…• …in the C/Python API a lot of “stuff” is structures.
• If we want to share it in multiple places, we need to tell the linker to expect it.• A little like a forward class declaration.
• File A...Static PyTypeObject foo = { ... };
• File Bextern PyTypeObject foo;…// Use foo as normal
SUGGESTED CODE STRUCTURE
• ScriptTopLevelFunctions.h• Has prototypes (only) for top-level functions
• ScriptTopLevelFunctions.cpp• Has bodies for the functions (minus the static keyword – why?)
• ScriptGameObject.h• Contains the C __script_GameObject structure (C “class”)
• ScriptGameObject.cpp• Has the (python) __script_GameObject Type
• ScriptManager.h• Has extern references to the __script_GameObjectType.• Contains the PyMethodDef array for the top-level functions • I got errors when I did this in ScriptTopLevelFunctions.cpp
• Has a PyInit_ssuge function (static is OK)• A C++ singleton
top related