| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
| 2 | <html> |
| 3 | <head> |
| 4 | <link rel="STYLESHEET" href="ext.css" type='text/css' /> |
| 5 | <link rel="SHORTCUT ICON" href="../icons/pyfav.png" type="image/png" /> |
| 6 | <link rel='start' href='../index.html' title='Python Documentation Index' /> |
| 7 | <link rel="first" href="ext.html" title='Extending and Embedding the Python Interpreter' /> |
| 8 | <link rel='contents' href='contents.html' title="Contents" /> |
| 9 | <link rel='last' href='about.html' title='About this document...' /> |
| 10 | <link rel='help' href='about.html' title='About this document...' /> |
| 11 | <link rel="next" href="extending-with-embedding.html" /> |
| 12 | <link rel="prev" href="lower-level-embedding.html" /> |
| 13 | <link rel="parent" href="embedding.html" /> |
| 14 | <link rel="next" href="extending-with-embedding.html" /> |
| 15 | <meta name='aesop' content='information' /> |
| 16 | <title>5.3 Pure Embedding </title> |
| 17 | </head> |
| 18 | <body> |
| 19 | <DIV CLASS="navigation"> |
| 20 | <div id='top-navigation-panel' xml:id='top-navigation-panel'> |
| 21 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 22 | <tr> |
| 23 | <td class='online-navigation'><a rel="prev" title="5.2 Beyond Very High" |
| 24 | href="lower-level-embedding.html"><img src='../icons/previous.png' |
| 25 | border='0' height='32' alt='Previous Page' width='32' /></A></td> |
| 26 | <td class='online-navigation'><a rel="parent" title="5. Embedding Python in" |
| 27 | href="embedding.html"><img src='../icons/up.png' |
| 28 | border='0' height='32' alt='Up One Level' width='32' /></A></td> |
| 29 | <td class='online-navigation'><a rel="next" title="5.4 Extending Embedded Python" |
| 30 | href="extending-with-embedding.html"><img src='../icons/next.png' |
| 31 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 32 | <td align="center" width="100%">Extending and Embedding the Python Interpreter</td> |
| 33 | <td class='online-navigation'><a rel="contents" title="Table of Contents" |
| 34 | href="contents.html"><img src='../icons/contents.png' |
| 35 | border='0' height='32' alt='Contents' width='32' /></A></td> |
| 36 | <td class='online-navigation'><img src='../icons/blank.png' |
| 37 | border='0' height='32' alt='' width='32' /></td> |
| 38 | <td class='online-navigation'><img src='../icons/blank.png' |
| 39 | border='0' height='32' alt='' width='32' /></td> |
| 40 | </tr></table> |
| 41 | <div class='online-navigation'> |
| 42 | <b class="navlabel">Previous:</b> |
| 43 | <a class="sectref" rel="prev" href="lower-level-embedding.html">5.2 Beyond Very High</A> |
| 44 | <b class="navlabel">Up:</b> |
| 45 | <a class="sectref" rel="parent" href="embedding.html">5. Embedding Python in</A> |
| 46 | <b class="navlabel">Next:</b> |
| 47 | <a class="sectref" rel="next" href="extending-with-embedding.html">5.4 Extending Embedded Python</A> |
| 48 | </div> |
| 49 | <hr /></div> |
| 50 | </DIV> |
| 51 | <!--End of Navigation Panel--> |
| 52 | |
| 53 | <H1><A NAME="SECTION007300000000000000000"></A><A NAME="pure-embedding"></A> |
| 54 | <BR> |
| 55 | 5.3 Pure Embedding |
| 56 | |
| 57 | </H1> |
| 58 | |
| 59 | <P> |
| 60 | The first program aims to execute a function in a Python |
| 61 | script. Like in the section about the very high level interface, |
| 62 | the Python interpreter does not directly interact with the |
| 63 | application (but that will change in the next section). |
| 64 | |
| 65 | <P> |
| 66 | The code to run a function defined in a Python script is: |
| 67 | |
| 68 | <P> |
| 69 | <div class="verbatim"> |
| 70 | <pre>#include <Python.h> |
| 71 | |
| 72 | int |
| 73 | main(int argc, char *argv[]) |
| 74 | { |
| 75 | PyObject *pName, *pModule, *pDict, *pFunc; |
| 76 | PyObject *pArgs, *pValue; |
| 77 | int i; |
| 78 | |
| 79 | if (argc < 3) { |
| 80 | fprintf(stderr,"Usage: call pythonfile funcname [args]\n"); |
| 81 | return 1; |
| 82 | } |
| 83 | |
| 84 | Py_Initialize(); |
| 85 | pName = PyString_FromString(argv[1]); |
| 86 | /* Error checking of pName left out */ |
| 87 | |
| 88 | pModule = PyImport_Import(pName); |
| 89 | Py_DECREF(pName); |
| 90 | |
| 91 | if (pModule != NULL) { |
| 92 | pFunc = PyDict_GetAttrString(pModule, argv[2]); |
| 93 | /* pFunc is a new reference */ |
| 94 | |
| 95 | if (pFunc && PyCallable_Check(pFunc)) { |
| 96 | pArgs = PyTuple_New(argc - 3); |
| 97 | for (i = 0; i < argc - 3; ++i) { |
| 98 | pValue = PyInt_FromLong(atoi(argv[i + 3])); |
| 99 | if (!pValue) { |
| 100 | Py_DECREF(pArgs); |
| 101 | Py_DECREF(pModule); |
| 102 | fprintf(stderr, "Cannot convert argument\n"); |
| 103 | return 1; |
| 104 | } |
| 105 | /* pValue reference stolen here: */ |
| 106 | PyTuple_SetItem(pArgs, i, pValue); |
| 107 | } |
| 108 | pValue = PyObject_CallObject(pFunc, pArgs); |
| 109 | Py_DECREF(pArgs); |
| 110 | if (pValue != NULL) { |
| 111 | printf("Result of call: %ld\n", PyInt_AsLong(pValue)); |
| 112 | Py_DECREF(pValue); |
| 113 | } |
| 114 | else { |
| 115 | Py_DECREF(pFunc); |
| 116 | Py_DECREF(pModule); |
| 117 | PyErr_Print(); |
| 118 | fprintf(stderr,"Call failed\n"); |
| 119 | return 1; |
| 120 | } |
| 121 | } |
| 122 | else { |
| 123 | if (PyErr_Occurred()) |
| 124 | PyErr_Print(); |
| 125 | fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]); |
| 126 | } |
| 127 | Py_XDECREF(pFunc); |
| 128 | Py_DECREF(pModule); |
| 129 | } |
| 130 | else { |
| 131 | PyErr_Print(); |
| 132 | fprintf(stderr, "Failed to load \"%s\"\n", argv[1]); |
| 133 | return 1; |
| 134 | } |
| 135 | Py_Finalize(); |
| 136 | return 0; |
| 137 | } |
| 138 | </pre> |
| 139 | <div class="footer"> |
| 140 | <a href="run-func.txt" type="text/plain">Download as text (original file name: <span class="file">run-func.c</span>).</a> |
| 141 | </div></div> |
| 142 | |
| 143 | <P> |
| 144 | This code loads a Python script using <code>argv[1]</code>, and calls the |
| 145 | function named in <code>argv[2]</code>. Its integer arguments are the other |
| 146 | values of the <code>argv</code> array. If you compile and link this |
| 147 | program (let's call the finished executable <b class="program">call</b>), and use |
| 148 | it to execute a Python script, such as: |
| 149 | |
| 150 | <P> |
| 151 | <div class="verbatim"><pre> |
| 152 | def multiply(a,b): |
| 153 | print "Will compute", a, "times", b |
| 154 | c = 0 |
| 155 | for i in range(0, a): |
| 156 | c = c + b |
| 157 | return c |
| 158 | </pre></div> |
| 159 | |
| 160 | <P> |
| 161 | then the result should be: |
| 162 | |
| 163 | <P> |
| 164 | <div class="verbatim"><pre> |
| 165 | $ call multiply multiply 3 2 |
| 166 | Will compute 3 times 2 |
| 167 | Result of call: 6 |
| 168 | </pre></div> |
| 169 | <P> |
| 170 | Although the program is quite large for its functionality, most of the |
| 171 | code is for data conversion between Python and C, and for error |
| 172 | reporting. The interesting part with respect to embedding Python |
| 173 | starts with |
| 174 | |
| 175 | <P> |
| 176 | <div class="verbatim"><pre> |
| 177 | Py_Initialize(); |
| 178 | pName = PyString_FromString(argv[1]); |
| 179 | /* Error checking of pName left out */ |
| 180 | pModule = PyImport_Import(pName); |
| 181 | </pre></div> |
| 182 | |
| 183 | <P> |
| 184 | After initializing the interpreter, the script is loaded using |
| 185 | <tt class="cfunction">PyImport_Import()</tt>. This routine needs a Python string |
| 186 | as its argument, which is constructed using the |
| 187 | <tt class="cfunction">PyString_FromString()</tt> data conversion routine. |
| 188 | |
| 189 | <P> |
| 190 | <div class="verbatim"><pre> |
| 191 | pFunc = PyObject_GetAttrString(pModule, argv[2]); |
| 192 | /* pFunc is a new reference */ |
| 193 | |
| 194 | if (pFunc && PyCallable_Check(pFunc)) { |
| 195 | ... |
| 196 | } |
| 197 | Py_XDECREF(pFunc); |
| 198 | </pre></div> |
| 199 | |
| 200 | <P> |
| 201 | Once the script is loaded, the name we're looking for is retrieved |
| 202 | using <tt class="cfunction">PyObject_GetAttrString()</tt>. If the name exists, and |
| 203 | the object returned is callable, you can safely assume that it is a |
| 204 | function. The program then proceeds by constructing a tuple of |
| 205 | arguments as normal. The call to the Python function is then made |
| 206 | with: |
| 207 | |
| 208 | <P> |
| 209 | <div class="verbatim"><pre> |
| 210 | pValue = PyObject_CallObject(pFunc, pArgs); |
| 211 | </pre></div> |
| 212 | |
| 213 | <P> |
| 214 | Upon return of the function, <code>pValue</code> is either <tt class="constant">NULL</tt> or it |
| 215 | contains a reference to the return value of the function. Be sure to |
| 216 | release the reference after examining the value. |
| 217 | |
| 218 | <P> |
| 219 | |
| 220 | <DIV CLASS="navigation"> |
| 221 | <div class='online-navigation'> |
| 222 | <p></p><hr /> |
| 223 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 224 | <tr> |
| 225 | <td class='online-navigation'><a rel="prev" title="5.2 Beyond Very High" |
| 226 | href="lower-level-embedding.html"><img src='../icons/previous.png' |
| 227 | border='0' height='32' alt='Previous Page' width='32' /></A></td> |
| 228 | <td class='online-navigation'><a rel="parent" title="5. Embedding Python in" |
| 229 | href="embedding.html"><img src='../icons/up.png' |
| 230 | border='0' height='32' alt='Up One Level' width='32' /></A></td> |
| 231 | <td class='online-navigation'><a rel="next" title="5.4 Extending Embedded Python" |
| 232 | href="extending-with-embedding.html"><img src='../icons/next.png' |
| 233 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 234 | <td align="center" width="100%">Extending and Embedding the Python Interpreter</td> |
| 235 | <td class='online-navigation'><a rel="contents" title="Table of Contents" |
| 236 | href="contents.html"><img src='../icons/contents.png' |
| 237 | border='0' height='32' alt='Contents' width='32' /></A></td> |
| 238 | <td class='online-navigation'><img src='../icons/blank.png' |
| 239 | border='0' height='32' alt='' width='32' /></td> |
| 240 | <td class='online-navigation'><img src='../icons/blank.png' |
| 241 | border='0' height='32' alt='' width='32' /></td> |
| 242 | </tr></table> |
| 243 | <div class='online-navigation'> |
| 244 | <b class="navlabel">Previous:</b> |
| 245 | <a class="sectref" rel="prev" href="lower-level-embedding.html">5.2 Beyond Very High</A> |
| 246 | <b class="navlabel">Up:</b> |
| 247 | <a class="sectref" rel="parent" href="embedding.html">5. Embedding Python in</A> |
| 248 | <b class="navlabel">Next:</b> |
| 249 | <a class="sectref" rel="next" href="extending-with-embedding.html">5.4 Extending Embedded Python</A> |
| 250 | </div> |
| 251 | </div> |
| 252 | <hr /> |
| 253 | <span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span> |
| 254 | </DIV> |
| 255 | <!--End of Navigation Panel--> |
| 256 | <ADDRESS> |
| 257 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. |
| 258 | </ADDRESS> |
| 259 | </BODY> |
| 260 | </HTML> |