Previous Section Next Section

24.3 Embedding Python

If you have an application already written in C or C++ (or any other classic compiled language), you may want to embed Python as your application's scripting language. To embed Python in languages other than C, the other language must be able to call C functions. In the following, I cover only the C view of things, since other languages vary widely regarding what you have to do in order to call C functions from them.

24.3.1 Installing Resident Extension Modules

In order for Python scripts to communicate with your application, your application must supply extension modules with Python-accessible functions and classes that expose your application's functionality. If these modules are linked with your application rather than residing in dynamic libraries that Python can load when necessary, register your modules with Python as additional built-in modules by calling the PyImport_AppendInittab C API function.

PyImport_AppendInittab

int PyImport_AppendInittab(char* name,void (*initfunc)(void))

name is the module name, which Python scripts use in import statements to access the module. initfunc is the module initialization function, taking no argument and returning no result, as covered earlier in this chapter (i.e., initfunc is the module's function that would be named initname for a normal extension module residing in a dynamic library). PyImport_AppendInittab must be called before calling Py_Initialize.

24.3.2 Setting Arguments

You may want to set the program name and arguments, which Python scripts can access as sys.argv, by calling either or both of the following C API functions.

Py_SetProgramName

void Py_SetProgramName(char* name)

Sets the program name, which Python scripts can access as sys.argv[0]. Must be called before calling Py_Initialize.

PySys_SetArgv

void PySys_SetArgv(int argc,char** argv)

Sets the program arguments, which Python scripts can access as sys.argv[1:]. Must be called after calling Py_Initialize.

24.3.3 Python Initialization and Finalization

After installing extra built-in modules and optionally setting the program name, your application initializes Python. At the end, when Python is no longer needed, your application finalizes Python. The relevant functions in the C API are as follows.

Py_Finalize

void Py_Finalize(void)

Frees all memory and other resources that Python is able to free. You should not make other Python C API calls after calling this function.

Py_Initialize

void Py_Initialize(void)

Initializes the Python environment. Make no other Python C API call before this one, except PyImport_AppendInittab and Py_SetProgramName, as covered earlier in this chapter.

24.3.4 Running Python Code

Your application can run Python source code from a character string or from a file. To run or compile Python source code, choose the mode of execution as one of the following three constants defined in Python.h:

Py_eval_input

The code is an expression to evaluate (like passing 'eval' to Python built-in function compile)

Py_file_input

The code is a block of one or more statements to execute (like 'exec' for compile—just like in that case, a trailing '\n' must close compound statements)

Py_single_input

The code is a single statement for interactive execution (like 'single' for compile—implicitly outputs the results of expression statements)

Running Python source code directly is similar to passing a source code string to Python statement exec or built-in function eval, or a source code file to built-in function execfile. Two general functions you can use for this task are the following.

PyRun_File

PyObject* PyRun_File(FILE* fp,char* filename,int start, 
PyObject* globals,PyObject* locals)

fp is a file of source code open for reading. filename is the name of the file, to use in error messages. start is one of the constants that define execution mode. globals and locals are dictionaries (may be the same dictionary twice) to use as global and local namespace for the execution. Returns the result of the expression when start is Py_eval_input, a new reference to Py_None otherwise, or NULL to indicate that an exception has been raised (often, but not always, due to a syntax error).

PyRun_String

PyObject* PyRun_String(char* astring,int start,
PyObject* globals,PyObject* locals)

Like PyRun_File, but the source code is in null-terminated string astring.

Dictionaries locals and globals are often new, empty dictionaries (most conveniently built by Py_BuildValue("{}")) or the dictionary of a module. PyImport_Import is a convenient way to obtain an existing module object; PyModule_GetDict obtains a module's dictionary. Sometimes you want to create a new module object on the fly and populate it with PyRun_ calls. To create a new, empty module, you can use the PyModule_New C API function.

PyModule_New

PyObject* PyModule_New(char* name)

Returns a new, empty module object for a module named name. Before the new object is usable, you must add to the object a string attribute named _ _file_ _. For example:

PyObject* newmod = PyModule_New("mymodule");
PyModule_AddStringConstant(newmod, "__file_  _",
    "<synthetic>");

After this code is run, module object newmod is ready; you can obtain the module's dictionary with PyModule_GetDict(newmod) and pass it directly to such functions as PyRun_String as the globals and possibly also the locals argument.

To run Python code repeatedly, and to discern the diagnosis of syntax errors from that of runtime exceptions raised by the code when it runs, you can compile the Python source to a code object, then keep the code object and run it repeatedly. This is just as true when using the C API as when dynamically executing from Python, as covered in Chapter 13. Two C API functions you can use for this task are the following.

Py_CompileString

PyObject* Py_CompileString(char* code,char* filename,int start)

code is a null-terminated string of source code. filename is the name of the file, to use in error messages. start is one of the constants that define execution mode. Returns the Python code object containing the bytecode, or NULL for syntax errors.

PyEval_EvalCode

PyObject* PyEval_EvalCode(PyObject* co,PyObject* globals,
PyObject* locals)

co is a Python code object, as returned by Py_CompileString, for example. globals and locals are dictionaries (may be the same dictionary twice) to use as global and local namespace for the execution. Returns the result of the expression when co was compiled with Py_eval_input, a new reference to Py_None otherwise, or NULL to indicate the execution has raised an exception.

    Previous Section Next Section