Example 20-28. PP4E\Integrate\Embed\Basics\embed-dict.c
/ make a new dictionary for code string namespace /
#include <Python.h>
main() {
int cval;
PyObject pdict, pval;
printf("embed-dict\n");
Py_Initialize();
/ make a new namespace /
pdict = PyDict_New();
PyDict_SetItemString(pdict, "builtins", PyEval_GetBuiltins());
PyDict_SetItemString(pdict, "Y", PyLong_FromLong(2)); / dict['Y'] = 2 /
PyRun_String("X = 99", Py_file_input, pdict, pdict); / run statements /
PyRun_String("X = X+Y", Py_file_input, pdict, pdict); / same X and Y /
pval = PyDict_GetItemString(pdict, "X"); / fetch dict['X'] /
PyArg_Parse(pval, "i", &cval); / convert to C /
printf("%d\n", cval); / result=101 /
Py_DECREF(pdict);
Py_Finalize();
}
When compiled and run, this C program creates this sort of output, tailored for this
use case:
.../PP4E/Integrate/Embed/Basics$ ./embed-dict
embed-dict
101
The output is different this time: it reflects the value of the Python variable X assigned
by the embedded Python code strings and fetched by C. In general, C can fetch module
attributes either by calling PyObject_GetAttrString with the module or by using
PyDict_GetItemString to index the module’s attribute dictionary (expression strings
work, too, but they are less direct). Here, there is no module at all, so dictionary in-
dexing is used to access the code’s namespace in C.
Besides allowing you to partition code string namespaces independent of any Python
module files on the underlying system, this scheme provides a natural communication
mechanism. Values that are stored in the new dictionary before code is run serve as
inputs, and names assigned by the embedded code can later be fetched out of the dic-
tionary to serve as code outputs. For instance, the variable Y in the second string run
refers to a name set to 2 by C; X is assigned by the Python code and fetched later by C
code as the printed result.
Basic Embedding Techniques | 1527