diff options
Diffstat (limited to 'Demo/embed')
-rw-r--r-- | Demo/embed/Makefile | 57 | ||||
-rw-r--r-- | Demo/embed/README | 19 | ||||
-rw-r--r-- | Demo/embed/demo.c | 74 | ||||
-rw-r--r-- | Demo/embed/importexc.c | 17 | ||||
-rw-r--r-- | Demo/embed/loop.c | 33 |
5 files changed, 200 insertions, 0 deletions
diff --git a/Demo/embed/Makefile b/Demo/embed/Makefile new file mode 100644 index 0000000..19ba344 --- /dev/null +++ b/Demo/embed/Makefile @@ -0,0 +1,57 @@ +# Makefile for embedded Python use demo. +# (This version originally written on Red Hat Linux 6.1; +# edit lines marked with XXX.) + +# XXX The compiler you are using +CC= gcc + +# XXX Top of the build tree and source tree +blddir= ../.. +srcdir= ../.. + +# Python version +VERSION= 2.7 + +# Compiler flags +OPT= -g +INCLUDES= -I$(srcdir)/Include -I$(blddir) +CFLAGS= $(OPT) +CPPFLAGS= $(INCLUDES) + +# The Python library +LIBPYTHON= $(blddir)/libpython$(VERSION).a + +# XXX edit LIBS (in particular) to match $(blddir)/Makefile +LIBS= -lnsl -ldl -lreadline -ltermcap -lieee -lpthread -lutil +LDFLAGS= -Xlinker -export-dynamic +SYSLIBS= -lm +MODLIBS= +ALLLIBS= $(LIBPYTHON) $(MODLIBS) $(LIBS) $(SYSLIBS) + +# Build the demo applications +all: demo loop importexc +demo: demo.o + $(CC) $(LDFLAGS) demo.o $(ALLLIBS) -o demo + +loop: loop.o + $(CC) $(LDFLAGS) loop.o $(ALLLIBS) -o loop + +importexc: importexc.o + $(CC) $(LDFLAGS) importexc.o $(ALLLIBS) -o importexc + +# Administrative targets + +test: demo + ./demo + +COMMAND="print 'hello world'" +looptest: loop + ./loop $(COMMAND) + +clean: + -rm -f *.o core + +clobber: clean + -rm -f *~ @* '#'* demo loop importexc + +realclean: clobber diff --git a/Demo/embed/README b/Demo/embed/README new file mode 100644 index 0000000..a0f7af8 --- /dev/null +++ b/Demo/embed/README @@ -0,0 +1,19 @@ +This directory show how to embed the Python interpreter in your own +application. The file demo.c shows you all that is needed in your C +code. + +To build it, you may have to edit the Makefile: + +1) set blddir to the directory where you built Python, if it isn't in +the source directory (../..) + +2) change the variables that together define the list of libraries +(MODLIBS, LIBS, SYSLIBS) to link with, to match their definitions in +$(blddir)/Modules/Makefile + +An additional test program, loop.c, is used to experiment with memory +leakage caused by repeated initialization and finalization of the +interpreter. It can be build by saying "make loop" and tested with +"make looptest". Command line usage is "./loop <python-command>", +e.g. "./loop 'print 2+2'" should spit out an endless number of lines +containing the number 4. diff --git a/Demo/embed/demo.c b/Demo/embed/demo.c new file mode 100644 index 0000000..00c5a0e --- /dev/null +++ b/Demo/embed/demo.c @@ -0,0 +1,74 @@ +/* Example of embedding Python in another program */ + +#include "Python.h" + +void initxyzzy(void); /* Forward */ + +main(int argc, char **argv) +{ + /* Pass argv[0] to the Python interpreter */ + Py_SetProgramName(argv[0]); + + /* Initialize the Python interpreter. Required. */ + Py_Initialize(); + + /* Add a static module */ + initxyzzy(); + + /* Define sys.argv. It is up to the application if you + want this; you can also leave it undefined (since the Python + code is generally not a main program it has no business + touching sys.argv...) + + If the third argument is true, sys.path is modified to include + either the directory containing the script named by argv[0], or + the current working directory. This can be risky; if you run + an application embedding Python in a directory controlled by + someone else, attackers could put a Trojan-horse module in the + directory (say, a file named os.py) that your application would + then import and run. + */ + PySys_SetArgvEx(argc, argv, 0); + + /* Do some application specific code */ + printf("Hello, brave new world\n\n"); + + /* Execute some Python statements (in module __main__) */ + PyRun_SimpleString("import sys\n"); + PyRun_SimpleString("print sys.builtin_module_names\n"); + PyRun_SimpleString("print sys.modules.keys()\n"); + PyRun_SimpleString("print sys.executable\n"); + PyRun_SimpleString("print sys.argv\n"); + + /* Note that you can call any public function of the Python + interpreter here, e.g. call_object(). */ + + /* Some more application specific code */ + printf("\nGoodbye, cruel world\n"); + + /* Exit, cleaning up the interpreter */ + Py_Exit(0); + /*NOTREACHED*/ +} + +/* A static module */ + +/* 'self' is not used */ +static PyObject * +xyzzy_foo(PyObject *self, PyObject* args) +{ + return PyInt_FromLong(42L); +} + +static PyMethodDef xyzzy_methods[] = { + {"foo", xyzzy_foo, METH_NOARGS, + "Return the meaning of everything."}, + {NULL, NULL} /* sentinel */ +}; + +void +initxyzzy(void) +{ + PyImport_AddModule("xyzzy"); + Py_InitModule("xyzzy", xyzzy_methods); +} diff --git a/Demo/embed/importexc.c b/Demo/embed/importexc.c new file mode 100644 index 0000000..375ce1b --- /dev/null +++ b/Demo/embed/importexc.c @@ -0,0 +1,17 @@ +#include <Python.h> + +char* cmd = "import exceptions"; + +int main() +{ + Py_Initialize(); + PyEval_InitThreads(); + PyRun_SimpleString(cmd); + Py_EndInterpreter(PyThreadState_Get()); + + Py_NewInterpreter(); + PyRun_SimpleString(cmd); + Py_Finalize(); + + return 0; +} diff --git a/Demo/embed/loop.c b/Demo/embed/loop.c new file mode 100644 index 0000000..2f7fe62 --- /dev/null +++ b/Demo/embed/loop.c @@ -0,0 +1,33 @@ +/* Simple program that repeatedly calls Py_Initialize(), does something, and + then calls Py_Finalize(). This should help finding leaks related to + initialization. */ + +#include "Python.h" + +main(int argc, char **argv) +{ + int count = -1; + char *command; + + if (argc < 2 || argc > 3) { + fprintf(stderr, "usage: loop <python-command> [count]\n"); + exit(2); + } + command = argv[1]; + + if (argc == 3) { + count = atoi(argv[2]); + } + + Py_SetProgramName(argv[0]); + + /* uncomment this if you don't want to load site.py */ + /* Py_NoSiteFlag = 1; */ + + while (count == -1 || --count >= 0 ) { + Py_Initialize(); + PyRun_SimpleString(command); + Py_Finalize(); + } + return 0; +} |