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