[2] | 1 | .. highlightlang:: c
|
---|
| 2 |
|
---|
| 3 |
|
---|
| 4 | .. _building-on-windows:
|
---|
| 5 |
|
---|
| 6 | ****************************************
|
---|
| 7 | Building C and C++ Extensions on Windows
|
---|
| 8 | ****************************************
|
---|
| 9 |
|
---|
| 10 | This chapter briefly explains how to create a Windows extension module for
|
---|
| 11 | Python using Microsoft Visual C++, and follows with more detailed background
|
---|
| 12 | information on how it works. The explanatory material is useful for both the
|
---|
| 13 | Windows programmer learning to build Python extensions and the Unix programmer
|
---|
| 14 | interested in producing software which can be successfully built on both Unix
|
---|
| 15 | and Windows.
|
---|
| 16 |
|
---|
| 17 | Module authors are encouraged to use the distutils approach for building
|
---|
| 18 | extension modules, instead of the one described in this section. You will still
|
---|
| 19 | need the C compiler that was used to build Python; typically Microsoft Visual
|
---|
| 20 | C++.
|
---|
| 21 |
|
---|
| 22 | .. note::
|
---|
| 23 |
|
---|
| 24 | This chapter mentions a number of filenames that include an encoded Python
|
---|
| 25 | version number. These filenames are represented with the version number shown
|
---|
| 26 | as ``XY``; in practice, ``'X'`` will be the major version number and ``'Y'``
|
---|
| 27 | will be the minor version number of the Python release you're working with. For
|
---|
| 28 | example, if you are using Python 2.2.1, ``XY`` will actually be ``22``.
|
---|
| 29 |
|
---|
| 30 |
|
---|
| 31 | .. _win-cookbook:
|
---|
| 32 |
|
---|
| 33 | A Cookbook Approach
|
---|
| 34 | ===================
|
---|
| 35 |
|
---|
| 36 | There are two approaches to building extension modules on Windows, just as there
|
---|
| 37 | are on Unix: use the :mod:`distutils` package to control the build process, or
|
---|
| 38 | do things manually. The distutils approach works well for most extensions;
|
---|
| 39 | documentation on using :mod:`distutils` to build and package extension modules
|
---|
| 40 | is available in :ref:`distutils-index`. This section describes the manual
|
---|
| 41 | approach to building Python extensions written in C or C++.
|
---|
| 42 |
|
---|
| 43 | To build extensions using these instructions, you need to have a copy of the
|
---|
| 44 | Python sources of the same version as your installed Python. You will need
|
---|
| 45 | Microsoft Visual C++ "Developer Studio"; project files are supplied for VC++
|
---|
| 46 | version 7.1, but you can use older versions of VC++. Notice that you should use
|
---|
| 47 | the same version of VC++that was used to build Python itself. The example files
|
---|
| 48 | described here are distributed with the Python sources in the
|
---|
| 49 | :file:`PC\\example_nt\\` directory.
|
---|
| 50 |
|
---|
| 51 | #. **Copy the example files** --- The :file:`example_nt` directory is a
|
---|
| 52 | subdirectory of the :file:`PC` directory, in order to keep all the PC-specific
|
---|
| 53 | files under the same directory in the source distribution. However, the
|
---|
| 54 | :file:`example_nt` directory can't actually be used from this location. You
|
---|
| 55 | first need to copy or move it up one level, so that :file:`example_nt` is a
|
---|
| 56 | sibling of the :file:`PC` and :file:`Include` directories. Do all your work
|
---|
| 57 | from within this new location.
|
---|
| 58 |
|
---|
| 59 | #. **Open the project** --- From VC++, use the :menuselection:`File --> Open
|
---|
| 60 | Solution` dialog (not :menuselection:`File --> Open`!). Navigate to and select
|
---|
| 61 | the file :file:`example.sln`, in the *copy* of the :file:`example_nt` directory
|
---|
| 62 | you made above. Click Open.
|
---|
| 63 |
|
---|
| 64 | #. **Build the example DLL** --- In order to check that everything is set up
|
---|
| 65 | right, try building:
|
---|
| 66 |
|
---|
| 67 | #. Select a configuration. This step is optional. Choose
|
---|
| 68 | :menuselection:`Build --> Configuration Manager --> Active Solution Configuration`
|
---|
| 69 | and select either :guilabel:`Release` or :guilabel:`Debug`. If you skip this
|
---|
| 70 | step, VC++ will use the Debug configuration by default.
|
---|
| 71 |
|
---|
| 72 | #. Build the DLL. Choose :menuselection:`Build --> Build Solution`. This
|
---|
| 73 | creates all intermediate and result files in a subdirectory called either
|
---|
| 74 | :file:`Debug` or :file:`Release`, depending on which configuration you selected
|
---|
| 75 | in the preceding step.
|
---|
| 76 |
|
---|
| 77 | #. **Testing the debug-mode DLL** --- Once the Debug build has succeeded, bring
|
---|
| 78 | up a DOS box, and change to the :file:`example_nt\\Debug` directory. You should
|
---|
| 79 | now be able to repeat the following session (``C>`` is the DOS prompt, ``>>>``
|
---|
| 80 | is the Python prompt; note that build information and various debug output from
|
---|
| 81 | Python may not match this screen dump exactly)::
|
---|
| 82 |
|
---|
| 83 | C>..\..\PCbuild\python_d
|
---|
| 84 | Adding parser accelerators ...
|
---|
| 85 | Done.
|
---|
| 86 | Python 2.2 (#28, Dec 19 2001, 23:26:37) [MSC 32 bit (Intel)] on win32
|
---|
| 87 | Type "copyright", "credits" or "license" for more information.
|
---|
| 88 | >>> import example
|
---|
| 89 | [4897 refs]
|
---|
| 90 | >>> example.foo()
|
---|
| 91 | Hello, world
|
---|
| 92 | [4903 refs]
|
---|
| 93 | >>>
|
---|
| 94 |
|
---|
| 95 | Congratulations! You've successfully built your first Python extension module.
|
---|
| 96 |
|
---|
| 97 | #. **Creating your own project** --- Choose a name and create a directory for
|
---|
| 98 | it. Copy your C sources into it. Note that the module source file name does
|
---|
| 99 | not necessarily have to match the module name, but the name of the
|
---|
| 100 | initialization function should match the module name --- you can only import a
|
---|
[391] | 101 | module :mod:`spam` if its initialization function is called :c:func:`initspam`,
|
---|
| 102 | and it should call :c:func:`Py_InitModule` with the string ``"spam"`` as its
|
---|
[2] | 103 | first argument (use the minimal :file:`example.c` in this directory as a guide).
|
---|
| 104 | By convention, it lives in a file called :file:`spam.c` or :file:`spammodule.c`.
|
---|
| 105 | The output file should be called :file:`spam.pyd` (in Release mode) or
|
---|
| 106 | :file:`spam_d.pyd` (in Debug mode). The extension :file:`.pyd` was chosen
|
---|
| 107 | to avoid confusion with a system library :file:`spam.dll` to which your module
|
---|
| 108 | could be a Python interface.
|
---|
| 109 |
|
---|
| 110 | .. versionchanged:: 2.5
|
---|
| 111 | Previously, file names like :file:`spam.dll` (in release mode) or
|
---|
| 112 | :file:`spam_d.dll` (in debug mode) were also recognized.
|
---|
| 113 |
|
---|
| 114 | Now your options are:
|
---|
| 115 |
|
---|
| 116 | #. Copy :file:`example.sln` and :file:`example.vcproj`, rename them to
|
---|
[391] | 117 | :file:`spam.\*`, and edit them by hand, or
|
---|
[2] | 118 |
|
---|
| 119 | #. Create a brand new project; instructions are below.
|
---|
| 120 |
|
---|
| 121 | In either case, copy :file:`example_nt\\example.def` to :file:`spam\\spam.def`,
|
---|
| 122 | and edit the new :file:`spam.def` so its second line contains the string
|
---|
| 123 | '``initspam``'. If you created a new project yourself, add the file
|
---|
| 124 | :file:`spam.def` to the project now. (This is an annoying little file with only
|
---|
| 125 | two lines. An alternative approach is to forget about the :file:`.def` file,
|
---|
| 126 | and add the option :option:`/export:initspam` somewhere to the Link settings, by
|
---|
| 127 | manually editing the setting in Project Properties dialog).
|
---|
| 128 |
|
---|
| 129 | #. **Creating a brand new project** --- Use the :menuselection:`File --> New
|
---|
| 130 | --> Project` dialog to create a new Project Workspace. Select :guilabel:`Visual
|
---|
| 131 | C++ Projects/Win32/ Win32 Project`, enter the name (``spam``), and make sure the
|
---|
| 132 | Location is set to parent of the :file:`spam` directory you have created (which
|
---|
| 133 | should be a direct subdirectory of the Python build tree, a sibling of
|
---|
| 134 | :file:`Include` and :file:`PC`). Select Win32 as the platform (in my version,
|
---|
| 135 | this is the only choice). Make sure the Create new workspace radio button is
|
---|
| 136 | selected. Click OK.
|
---|
| 137 |
|
---|
| 138 | You should now create the file :file:`spam.def` as instructed in the previous
|
---|
| 139 | section. Add the source files to the project, using :menuselection:`Project -->
|
---|
| 140 | Add Existing Item`. Set the pattern to ``*.*`` and select both :file:`spam.c`
|
---|
| 141 | and :file:`spam.def` and click OK. (Inserting them one by one is fine too.)
|
---|
| 142 |
|
---|
| 143 | Now open the :menuselection:`Project --> spam properties` dialog. You only need
|
---|
| 144 | to change a few settings. Make sure :guilabel:`All Configurations` is selected
|
---|
| 145 | from the :guilabel:`Settings for:` dropdown list. Select the C/C++ tab. Choose
|
---|
| 146 | the General category in the popup menu at the top. Type the following text in
|
---|
| 147 | the entry box labeled :guilabel:`Additional Include Directories`::
|
---|
| 148 |
|
---|
| 149 | ..\Include,..\PC
|
---|
| 150 |
|
---|
| 151 | Then, choose the General category in the Linker tab, and enter ::
|
---|
| 152 |
|
---|
| 153 | ..\PCbuild
|
---|
| 154 |
|
---|
| 155 | in the text box labelled :guilabel:`Additional library Directories`.
|
---|
| 156 |
|
---|
| 157 | Now you need to add some mode-specific settings:
|
---|
| 158 |
|
---|
| 159 | Select :guilabel:`Release` in the :guilabel:`Configuration` dropdown list.
|
---|
| 160 | Choose the :guilabel:`Link` tab, choose the :guilabel:`Input` category, and
|
---|
| 161 | append ``pythonXY.lib`` to the list in the :guilabel:`Additional Dependencies`
|
---|
| 162 | box.
|
---|
| 163 |
|
---|
| 164 | Select :guilabel:`Debug` in the :guilabel:`Configuration` dropdown list, and
|
---|
| 165 | append ``pythonXY_d.lib`` to the list in the :guilabel:`Additional Dependencies`
|
---|
| 166 | box. Then click the C/C++ tab, select :guilabel:`Code Generation`, and select
|
---|
| 167 | :guilabel:`Multi-threaded Debug DLL` from the :guilabel:`Runtime library`
|
---|
| 168 | dropdown list.
|
---|
| 169 |
|
---|
| 170 | Select :guilabel:`Release` again from the :guilabel:`Configuration` dropdown
|
---|
| 171 | list. Select :guilabel:`Multi-threaded DLL` from the :guilabel:`Runtime
|
---|
| 172 | library` dropdown list.
|
---|
| 173 |
|
---|
| 174 | If your module creates a new type, you may have trouble with this line::
|
---|
| 175 |
|
---|
| 176 | PyObject_HEAD_INIT(&PyType_Type)
|
---|
| 177 |
|
---|
[391] | 178 | Static type object initializers in extension modules may cause
|
---|
| 179 | compiles to fail with an error message like "initializer not a
|
---|
| 180 | constant". This shows up when building DLL under MSVC. Change it to::
|
---|
[2] | 181 |
|
---|
| 182 | PyObject_HEAD_INIT(NULL)
|
---|
| 183 |
|
---|
| 184 | and add the following to the module initialization function::
|
---|
| 185 |
|
---|
[391] | 186 | if (PyType_Ready(&MyObject_Type) < 0)
|
---|
| 187 | return NULL;
|
---|
[2] | 188 |
|
---|
| 189 |
|
---|
| 190 | .. _dynamic-linking:
|
---|
| 191 |
|
---|
| 192 | Differences Between Unix and Windows
|
---|
| 193 | ====================================
|
---|
| 194 |
|
---|
| 195 | .. sectionauthor:: Chris Phoenix <cphoenix@best.com>
|
---|
| 196 |
|
---|
| 197 |
|
---|
| 198 | Unix and Windows use completely different paradigms for run-time loading of
|
---|
| 199 | code. Before you try to build a module that can be dynamically loaded, be aware
|
---|
| 200 | of how your system works.
|
---|
| 201 |
|
---|
| 202 | In Unix, a shared object (:file:`.so`) file contains code to be used by the
|
---|
| 203 | program, and also the names of functions and data that it expects to find in the
|
---|
| 204 | program. When the file is joined to the program, all references to those
|
---|
| 205 | functions and data in the file's code are changed to point to the actual
|
---|
| 206 | locations in the program where the functions and data are placed in memory.
|
---|
| 207 | This is basically a link operation.
|
---|
| 208 |
|
---|
| 209 | In Windows, a dynamic-link library (:file:`.dll`) file has no dangling
|
---|
| 210 | references. Instead, an access to functions or data goes through a lookup
|
---|
| 211 | table. So the DLL code does not have to be fixed up at runtime to refer to the
|
---|
| 212 | program's memory; instead, the code already uses the DLL's lookup table, and the
|
---|
| 213 | lookup table is modified at runtime to point to the functions and data.
|
---|
| 214 |
|
---|
| 215 | In Unix, there is only one type of library file (:file:`.a`) which contains code
|
---|
| 216 | from several object files (:file:`.o`). During the link step to create a shared
|
---|
| 217 | object file (:file:`.so`), the linker may find that it doesn't know where an
|
---|
| 218 | identifier is defined. The linker will look for it in the object files in the
|
---|
| 219 | libraries; if it finds it, it will include all the code from that object file.
|
---|
| 220 |
|
---|
| 221 | In Windows, there are two types of library, a static library and an import
|
---|
| 222 | library (both called :file:`.lib`). A static library is like a Unix :file:`.a`
|
---|
| 223 | file; it contains code to be included as necessary. An import library is
|
---|
| 224 | basically used only to reassure the linker that a certain identifier is legal,
|
---|
| 225 | and will be present in the program when the DLL is loaded. So the linker uses
|
---|
| 226 | the information from the import library to build the lookup table for using
|
---|
| 227 | identifiers that are not included in the DLL. When an application or a DLL is
|
---|
| 228 | linked, an import library may be generated, which will need to be used for all
|
---|
| 229 | future DLLs that depend on the symbols in the application or DLL.
|
---|
| 230 |
|
---|
| 231 | Suppose you are building two dynamic-load modules, B and C, which should share
|
---|
| 232 | another block of code A. On Unix, you would *not* pass :file:`A.a` to the
|
---|
| 233 | linker for :file:`B.so` and :file:`C.so`; that would cause it to be included
|
---|
| 234 | twice, so that B and C would each have their own copy. In Windows, building
|
---|
| 235 | :file:`A.dll` will also build :file:`A.lib`. You *do* pass :file:`A.lib` to the
|
---|
| 236 | linker for B and C. :file:`A.lib` does not contain code; it just contains
|
---|
| 237 | information which will be used at runtime to access A's code.
|
---|
| 238 |
|
---|
| 239 | In Windows, using an import library is sort of like using ``import spam``; it
|
---|
| 240 | gives you access to spam's names, but does not create a separate copy. On Unix,
|
---|
| 241 | linking with a library is more like ``from spam import *``; it does create a
|
---|
| 242 | separate copy.
|
---|
| 243 |
|
---|
| 244 |
|
---|
| 245 | .. _win-dlls:
|
---|
| 246 |
|
---|
| 247 | Using DLLs in Practice
|
---|
| 248 | ======================
|
---|
| 249 |
|
---|
| 250 | .. sectionauthor:: Chris Phoenix <cphoenix@best.com>
|
---|
| 251 |
|
---|
| 252 |
|
---|
| 253 | Windows Python is built in Microsoft Visual C++; using other compilers may or
|
---|
| 254 | may not work (though Borland seems to). The rest of this section is MSVC++
|
---|
| 255 | specific.
|
---|
| 256 |
|
---|
| 257 | When creating DLLs in Windows, you must pass :file:`pythonXY.lib` to the linker.
|
---|
| 258 | To build two DLLs, spam and ni (which uses C functions found in spam), you could
|
---|
| 259 | use these commands::
|
---|
| 260 |
|
---|
| 261 | cl /LD /I/python/include spam.c ../libs/pythonXY.lib
|
---|
| 262 | cl /LD /I/python/include ni.c spam.lib ../libs/pythonXY.lib
|
---|
| 263 |
|
---|
| 264 | The first command created three files: :file:`spam.obj`, :file:`spam.dll` and
|
---|
| 265 | :file:`spam.lib`. :file:`Spam.dll` does not contain any Python functions (such
|
---|
[391] | 266 | as :c:func:`PyArg_ParseTuple`), but it does know how to find the Python code
|
---|
[2] | 267 | thanks to :file:`pythonXY.lib`.
|
---|
| 268 |
|
---|
| 269 | The second command created :file:`ni.dll` (and :file:`.obj` and :file:`.lib`),
|
---|
| 270 | which knows how to find the necessary functions from spam, and also from the
|
---|
| 271 | Python executable.
|
---|
| 272 |
|
---|
| 273 | Not every identifier is exported to the lookup table. If you want any other
|
---|
| 274 | modules (including Python) to be able to see your identifiers, you have to say
|
---|
| 275 | ``_declspec(dllexport)``, as in ``void _declspec(dllexport) initspam(void)`` or
|
---|
| 276 | ``PyObject _declspec(dllexport) *NiGetSpamData(void)``.
|
---|
| 277 |
|
---|
| 278 | Developer Studio will throw in a lot of import libraries that you do not really
|
---|
| 279 | need, adding about 100K to your executable. To get rid of them, use the Project
|
---|
| 280 | Settings dialog, Link tab, to specify *ignore default libraries*. Add the
|
---|
| 281 | correct :file:`msvcrtxx.lib` to the list of libraries.
|
---|
| 282 |
|
---|