| 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="prev" href="cplusplus.html" /> |
| 12 | <link rel="parent" href="intro.html" /> |
| 13 | <link rel="next" href="defining-new-types.html" /> |
| 14 | <meta name='aesop' content='information' /> |
| 15 | <title>1.12 Providing a C API for an Extension Module |
| 16 | </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="1.11 Writing Extensions in" |
| 24 | href="cplusplus.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="1. Extending Python with" |
| 27 | href="intro.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="2. Defining New Types" |
| 30 | href="defining-new-types.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="cplusplus.html">1.11 Writing Extensions in</A> |
| 44 | <b class="navlabel">Up:</b> |
| 45 | <a class="sectref" rel="parent" href="intro.html">1. Extending Python with</A> |
| 46 | <b class="navlabel">Next:</b> |
| 47 | <a class="sectref" rel="next" href="defining-new-types.html">2. Defining New Types</A> |
| 48 | </div> |
| 49 | <hr /></div> |
| 50 | </DIV> |
| 51 | <!--End of Navigation Panel--> |
| 52 | |
| 53 | <H1><A NAME="SECTION0031200000000000000000"></A><A NAME="using-cobjects"></A> |
| 54 | <BR> |
| 55 | 1.12 Providing a C API for an Extension Module |
| 56 | |
| 57 | </H1> |
| 58 | |
| 59 | <P> |
| 60 | Many extension modules just provide new functions and types to be |
| 61 | used from Python, but sometimes the code in an extension module can |
| 62 | be useful for other extension modules. For example, an extension |
| 63 | module could implement a type ``collection'' which works like lists |
| 64 | without order. Just like the standard Python list type has a C API |
| 65 | which permits extension modules to create and manipulate lists, this |
| 66 | new collection type should have a set of C functions for direct |
| 67 | manipulation from other extension modules. |
| 68 | |
| 69 | <P> |
| 70 | At first sight this seems easy: just write the functions (without |
| 71 | declaring them <tt class="keyword">static</tt>, of course), provide an appropriate |
| 72 | header file, and document the C API. And in fact this would work if |
| 73 | all extension modules were always linked statically with the Python |
| 74 | interpreter. When modules are used as shared libraries, however, the |
| 75 | symbols defined in one module may not be visible to another module. |
| 76 | The details of visibility depend on the operating system; some systems |
| 77 | use one global namespace for the Python interpreter and all extension |
| 78 | modules (Windows, for example), whereas others require an explicit |
| 79 | list of imported symbols at module link time (AIX is one example), or |
| 80 | offer a choice of different strategies (most Unices). And even if |
| 81 | symbols are globally visible, the module whose functions one wishes to |
| 82 | call might not have been loaded yet! |
| 83 | |
| 84 | <P> |
| 85 | Portability therefore requires not to make any assumptions about |
| 86 | symbol visibility. This means that all symbols in extension modules |
| 87 | should be declared <tt class="keyword">static</tt>, except for the module's |
| 88 | initialization function, in order to avoid name clashes with other |
| 89 | extension modules (as discussed in section <A href="methodTable.html#methodTable">1.4</A>). And it |
| 90 | means that symbols that <em>should</em> be accessible from other |
| 91 | extension modules must be exported in a different way. |
| 92 | |
| 93 | <P> |
| 94 | Python provides a special mechanism to pass C-level information |
| 95 | (pointers) from one extension module to another one: CObjects. |
| 96 | A CObject is a Python data type which stores a pointer (<tt class="ctype">void |
| 97 | *</tt>). CObjects can only be created and accessed via their C API, but |
| 98 | they can be passed around like any other Python object. In particular, |
| 99 | they can be assigned to a name in an extension module's namespace. |
| 100 | Other extension modules can then import this module, retrieve the |
| 101 | value of this name, and then retrieve the pointer from the CObject. |
| 102 | |
| 103 | <P> |
| 104 | There are many ways in which CObjects can be used to export the C API |
| 105 | of an extension module. Each name could get its own CObject, or all C |
| 106 | API pointers could be stored in an array whose address is published in |
| 107 | a CObject. And the various tasks of storing and retrieving the pointers |
| 108 | can be distributed in different ways between the module providing the |
| 109 | code and the client modules. |
| 110 | |
| 111 | <P> |
| 112 | The following example demonstrates an approach that puts most of the |
| 113 | burden on the writer of the exporting module, which is appropriate |
| 114 | for commonly used library modules. It stores all C API pointers |
| 115 | (just one in the example!) in an array of <tt class="ctype">void</tt> pointers which |
| 116 | becomes the value of a CObject. The header file corresponding to |
| 117 | the module provides a macro that takes care of importing the module |
| 118 | and retrieving its C API pointers; client modules only have to call |
| 119 | this macro before accessing the C API. |
| 120 | |
| 121 | <P> |
| 122 | The exporting module is a modification of the <tt class="module">spam</tt> module from |
| 123 | section <A href="simpleExample.html#simpleExample">1.1</A>. The function <tt class="function">spam.system()</tt> |
| 124 | does not call the C library function <tt class="cfunction">system()</tt> directly, |
| 125 | but a function <tt class="cfunction">PySpam_System()</tt>, which would of course do |
| 126 | something more complicated in reality (such as adding ``spam'' to |
| 127 | every command). This function <tt class="cfunction">PySpam_System()</tt> is also |
| 128 | exported to other extension modules. |
| 129 | |
| 130 | <P> |
| 131 | The function <tt class="cfunction">PySpam_System()</tt> is a plain C function, |
| 132 | declared <tt class="keyword">static</tt> like everything else: |
| 133 | |
| 134 | <P> |
| 135 | <div class="verbatim"><pre> |
| 136 | static int |
| 137 | PySpam_System(const char *command) |
| 138 | { |
| 139 | return system(command); |
| 140 | } |
| 141 | </pre></div> |
| 142 | |
| 143 | <P> |
| 144 | The function <tt class="cfunction">spam_system()</tt> is modified in a trivial way: |
| 145 | |
| 146 | <P> |
| 147 | <div class="verbatim"><pre> |
| 148 | static PyObject * |
| 149 | spam_system(PyObject *self, PyObject *args) |
| 150 | { |
| 151 | const char *command; |
| 152 | int sts; |
| 153 | |
| 154 | if (!PyArg_ParseTuple(args, "s", &command)) |
| 155 | return NULL; |
| 156 | sts = PySpam_System(command); |
| 157 | return Py_BuildValue("i", sts); |
| 158 | } |
| 159 | </pre></div> |
| 160 | |
| 161 | <P> |
| 162 | In the beginning of the module, right after the line |
| 163 | |
| 164 | <P> |
| 165 | <div class="verbatim"><pre> |
| 166 | #include "Python.h" |
| 167 | </pre></div> |
| 168 | |
| 169 | <P> |
| 170 | two more lines must be added: |
| 171 | |
| 172 | <P> |
| 173 | <div class="verbatim"><pre> |
| 174 | #define SPAM_MODULE |
| 175 | #include "spammodule.h" |
| 176 | </pre></div> |
| 177 | |
| 178 | <P> |
| 179 | The <code>#define</code> is used to tell the header file that it is being |
| 180 | included in the exporting module, not a client module. Finally, |
| 181 | the module's initialization function must take care of initializing |
| 182 | the C API pointer array: |
| 183 | |
| 184 | <P> |
| 185 | <div class="verbatim"><pre> |
| 186 | PyMODINIT_FUNC |
| 187 | initspam(void) |
| 188 | { |
| 189 | PyObject *m; |
| 190 | static void *PySpam_API[PySpam_API_pointers]; |
| 191 | PyObject *c_api_object; |
| 192 | |
| 193 | m = Py_InitModule("spam", SpamMethods); |
| 194 | |
| 195 | /* Initialize the C API pointer array */ |
| 196 | PySpam_API[PySpam_System_NUM] = (void *)PySpam_System; |
| 197 | |
| 198 | /* Create a CObject containing the API pointer array's address */ |
| 199 | c_api_object = PyCObject_FromVoidPtr((void *)PySpam_API, NULL); |
| 200 | |
| 201 | if (c_api_object != NULL) |
| 202 | PyModule_AddObject(m, "_C_API", c_api_object); |
| 203 | } |
| 204 | </pre></div> |
| 205 | |
| 206 | <P> |
| 207 | Note that <code>PySpam_API</code> is declared <tt class="keyword">static</tt>; otherwise |
| 208 | the pointer array would disappear when <tt class="function">initspam()</tt> terminates! |
| 209 | |
| 210 | <P> |
| 211 | The bulk of the work is in the header file <span class="file">spammodule.h</span>, |
| 212 | which looks like this: |
| 213 | |
| 214 | <P> |
| 215 | <div class="verbatim"><pre> |
| 216 | #ifndef Py_SPAMMODULE_H |
| 217 | #define Py_SPAMMODULE_H |
| 218 | #ifdef __cplusplus |
| 219 | extern "C" { |
| 220 | #endif |
| 221 | |
| 222 | /* Header file for spammodule */ |
| 223 | |
| 224 | /* C API functions */ |
| 225 | #define PySpam_System_NUM 0 |
| 226 | #define PySpam_System_RETURN int |
| 227 | #define PySpam_System_PROTO (const char *command) |
| 228 | |
| 229 | /* Total number of C API pointers */ |
| 230 | #define PySpam_API_pointers 1 |
| 231 | |
| 232 | |
| 233 | #ifdef SPAM_MODULE |
| 234 | /* This section is used when compiling spammodule.c */ |
| 235 | |
| 236 | static PySpam_System_RETURN PySpam_System PySpam_System_PROTO; |
| 237 | |
| 238 | #else |
| 239 | /* This section is used in modules that use spammodule's API */ |
| 240 | |
| 241 | static void **PySpam_API; |
| 242 | |
| 243 | #define PySpam_System \ |
| 244 | (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM]) |
| 245 | |
| 246 | /* Return -1 and set exception on error, 0 on success. */ |
| 247 | static int |
| 248 | import_spam(void) |
| 249 | { |
| 250 | PyObject *module = PyImport_ImportModule("spam"); |
| 251 | |
| 252 | if (module != NULL) { |
| 253 | PyObject *c_api_object = PyObject_GetAttrString(module, "_C_API"); |
| 254 | if (c_api_object == NULL) |
| 255 | return -1; |
| 256 | if (PyCObject_Check(c_api_object)) |
| 257 | PySpam_API = (void **)PyCObject_AsVoidPtr(c_api_object); |
| 258 | Py_DECREF(c_api_object); |
| 259 | } |
| 260 | return 0; |
| 261 | } |
| 262 | |
| 263 | #endif |
| 264 | |
| 265 | #ifdef __cplusplus |
| 266 | } |
| 267 | #endif |
| 268 | |
| 269 | #endif /* !defined(Py_SPAMMODULE_H) */ |
| 270 | </pre></div> |
| 271 | |
| 272 | <P> |
| 273 | All that a client module must do in order to have access to the |
| 274 | function <tt class="cfunction">PySpam_System()</tt> is to call the function (or |
| 275 | rather macro) <tt class="cfunction">import_spam()</tt> in its initialization |
| 276 | function: |
| 277 | |
| 278 | <P> |
| 279 | <div class="verbatim"><pre> |
| 280 | PyMODINIT_FUNC |
| 281 | initclient(void) |
| 282 | { |
| 283 | PyObject *m; |
| 284 | |
| 285 | Py_InitModule("client", ClientMethods); |
| 286 | if (import_spam() < 0) |
| 287 | return; |
| 288 | /* additional initialization can happen here */ |
| 289 | } |
| 290 | </pre></div> |
| 291 | |
| 292 | <P> |
| 293 | The main disadvantage of this approach is that the file |
| 294 | <span class="file">spammodule.h</span> is rather complicated. However, the |
| 295 | basic structure is the same for each function that is |
| 296 | exported, so it has to be learned only once. |
| 297 | |
| 298 | <P> |
| 299 | Finally it should be mentioned that CObjects offer additional |
| 300 | functionality, which is especially useful for memory allocation and |
| 301 | deallocation of the pointer stored in a CObject. The details |
| 302 | are described in the <em class="citetitle"><a |
| 303 | href="../api/api.html" |
| 304 | title="Python/C API |
| 305 | Reference Manual" |
| 306 | >Python/C API |
| 307 | Reference Manual</a></em> in the section |
| 308 | ``<a class="ulink" href="../api/cObjects.html" |
| 309 | >CObjects</a>'' and in the implementation |
| 310 | of CObjects (files <span class="file">Include/cobject.h</span> and |
| 311 | <span class="file">Objects/cobject.c</span> in the Python source code distribution). |
| 312 | |
| 313 | <DIV CLASS="navigation"> |
| 314 | <div class='online-navigation'> |
| 315 | <p></p><hr /> |
| 316 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 317 | <tr> |
| 318 | <td class='online-navigation'><a rel="prev" title="1.11 Writing Extensions in" |
| 319 | href="cplusplus.html"><img src='../icons/previous.png' |
| 320 | border='0' height='32' alt='Previous Page' width='32' /></A></td> |
| 321 | <td class='online-navigation'><a rel="parent" title="1. Extending Python with" |
| 322 | href="intro.html"><img src='../icons/up.png' |
| 323 | border='0' height='32' alt='Up One Level' width='32' /></A></td> |
| 324 | <td class='online-navigation'><a rel="next" title="2. Defining New Types" |
| 325 | href="defining-new-types.html"><img src='../icons/next.png' |
| 326 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 327 | <td align="center" width="100%">Extending and Embedding the Python Interpreter</td> |
| 328 | <td class='online-navigation'><a rel="contents" title="Table of Contents" |
| 329 | href="contents.html"><img src='../icons/contents.png' |
| 330 | border='0' height='32' alt='Contents' width='32' /></A></td> |
| 331 | <td class='online-navigation'><img src='../icons/blank.png' |
| 332 | border='0' height='32' alt='' width='32' /></td> |
| 333 | <td class='online-navigation'><img src='../icons/blank.png' |
| 334 | border='0' height='32' alt='' width='32' /></td> |
| 335 | </tr></table> |
| 336 | <div class='online-navigation'> |
| 337 | <b class="navlabel">Previous:</b> |
| 338 | <a class="sectref" rel="prev" href="cplusplus.html">1.11 Writing Extensions in</A> |
| 339 | <b class="navlabel">Up:</b> |
| 340 | <a class="sectref" rel="parent" href="intro.html">1. Extending Python with</A> |
| 341 | <b class="navlabel">Next:</b> |
| 342 | <a class="sectref" rel="next" href="defining-new-types.html">2. Defining New Types</A> |
| 343 | </div> |
| 344 | </div> |
| 345 | <hr /> |
| 346 | <span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span> |
| 347 | </DIV> |
| 348 | <!--End of Navigation Panel--> |
| 349 | <ADDRESS> |
| 350 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. |
| 351 | </ADDRESS> |
| 352 | </BODY> |
| 353 | </HTML> |