SitemapMcMillan Enterprises, Inc.Python Pages Sockets HOWTO Distributing Python Programs A Python C++ API Embedding Python Scripting Your App with Python Stackless Python MkSQL Import Hooks Java Samples Sponsoring ME Inc. About ME Inc. |
Scripting Your App With PythonOK, so you've got years of effort invested in your app, and you're not about to admit that rewriting it in Python would let you fix some pesky design flaws and make user-extensibility trivial (as well as getting you 90% of the way to cross-platform). All you want is to let your users script your application.
What I will show you is how simple it is to both embed and extend at the same time. In the following code, pretend that the "inc" method is non-trivial. It could, for example, be called "getRoot" and return a Python wrapper for your application's currently active Document object.
#include "Python.h"
void init_pyextension();
int main(int argc, char* argv[])
{
long answer;
PyObject *modname, *mod, *mdict, *func, *rslt;
Py_Initialize();
init_pyextension();
modname = PyString_FromString("testqqq");
mod = PyImport_Import(modname);
if (mod) {
mdict = PyModule_GetDict(mod);
func = PyDict_GetItemString(mdict, "doit"); /* borrowed reference */
if (func) {
if (PyCallable_Check(func)) {
rslt = PyObject_CallFunction(func, "(s)", "this is a test");
if (rslt) {
answer = PyInt_AsLong(rslt);
Py_XDECREF(rslt);
}
}
}
Py_XDECREF(mod);
}
Py_XDECREF(modname);
Py_Finalize();
return 0;
}
/* now a method we need to expose to Python */
long inc(long i) {
return ++i;
}
/* and the magic that exposes it - a builtin module */
/* first, the wrapper function */
static PyObject *py_inc(PyObject *self, PyObject *args)
{
long i;
if (!PyArg_ParseTuple(args, "l", &i))
return NULL;
return Py_BuildValue("l", inc(i));
}
/* now the module's function table */
static PyMethodDef genius_methods[] = {
{"inc", py_inc, 1, "a silly example method"},
{NULL, NULL} /* sentinel */
};
/* Python will call this when the module is imported */
void init_pyextension()
{
PyImport_AddModule("genius");
Py_InitModule("genius", genius_methods);
}
A Note On ThreadsWhen embedding, threads are either no problem at all, or an absolute nightmare. If you are single-threaded, they are obviously no problem. If only one thread is running Python, it is no problem. Callbacks are not normally a problem, either, since they almost always occur on the same thread that triggered them. If you will be using multiple threads with Python, you will have to be very careful. You will have to make sure that Python is in threading mode (normally by calling One approach is get ahold of the If you don't mind using C++, see SCXX, which can take care of this for you. |
| copyright 1999-2002 McMillan Enterprises, Inc. |
|