#include "PyTest.h" using namespace std; struct FuncID { short id; // An index number of the function. PyObject* cbf; // Pointer to the callback function. }; Array FunctionsList; PyObject* newmodule_RegisterFunction ( PyObject* pSelf, PyObject* pArgs ) { short index = 0; PyObject* CallbackFunction = NULL; if ( !PyArg_ParseTuple ( pArgs, "lO", &index, &CallbackFunction ) ) return NULL; if ( !PyCallable_Check ( CallbackFunction ) ) { PyErr_SetString ( PyExc_StandardError, "The object should be callable!" ); return NULL; } // Make sure the index isn't in the list already. for ( int i = 0; FunctionsList.GetCount(); i++ ) { if ( FunctionsList[i].id == index ) { // Sorry mates. return Py_BuildValue ( "i", 0 ); } } // And most important, add a reference to it! Py_INCREF ( CallbackFunction ); // Try to insert it to the list. FuncID info = {index, CallbackFunction}; try { FunctionsList.Add(info); } catch ( ... ) { // Oh uh! Py_DECREF ( CallbackFunction ); PyErr_SetString ( PyExc_StandardError, "An error occurred while inserting the given function into the DB!" ); return NULL; } return Py_BuildValue ( "i", 1 ); } PyObject* newmodule_CallFunctionByID ( PyObject* pSelf, PyObject* pArgs ) { short index = 0; if ( !PyArg_ParseTuple ( pArgs, "l", &index ) ) return NULL; // Find the ID in the list, and call it's appropriate function. for ( int i = 0; FunctionsList.GetCount(); i++ ) { if ( FunctionsList[i].id == index ) { // We pass no args, I leave it for you :) // Py_XDECREF checks if the object isn't NULL first. PyObject* ret = PyEval_CallObject ( FunctionsList[i].cbf, NULL ); Py_XDECREF ( ret ); Py_INCREF ( Py_None ); return Py_None; } } // Damn function wasn't found. return Py_BuildValue ( "i", 0 ); } static PyMethodDef newmoduleMethods[] = { {"RegisterFunction", newmodule_RegisterFunction, METH_VARARGS, "Register a function to a given ID."}, {"CallFunctionByID", newmodule_CallFunctionByID, METH_VARARGS, "Call a registered function by its ID."}, {NULL, NULL, 0, NULL} }; void InitNewModule() { // When you'll run in Python: newmodule.__doc__, you'll get the last string. :) Py_InitModule3 ( "newmodule", newmoduleMethods, "This is a new module" ); PyModule_AddIntConstant ( PyImport_AddModule ( "newmodule" ), "INT1", 2003 ); PyModule_AddStringConstant ( PyImport_AddModule ( "newmodule" ), "STR1", "http://ragestorm.net" ); FunctionsList.Clear(); } void DestroyNewModule() { // Clean up the list. for ( int i = 0; FunctionsList.GetCount(); i++ ) { Py_DECREF ( FunctionsList[i].cbf ); } FunctionsList.Clear(); // And free the newmodule. } // void ExtendPython() { Cout() << "Extending Python:"<< EOL; InitNewModule(); }