Commit | Line | Data |
---|---|---|
920dae64 AT |
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> |