diff options
Diffstat (limited to 'Doc/ext/windows.tex')
-rw-r--r-- | Doc/ext/windows.tex | 320 |
1 files changed, 0 insertions, 320 deletions
diff --git a/Doc/ext/windows.tex b/Doc/ext/windows.tex deleted file mode 100644 index f9de548..0000000 --- a/Doc/ext/windows.tex +++ /dev/null @@ -1,320 +0,0 @@ -\chapter{Building C and \Cpp{} Extensions on Windows% - \label{building-on-windows}} - - -This chapter briefly explains how to create a Windows extension module -for Python using Microsoft Visual \Cpp, and follows with more -detailed background information on how it works. The explanatory -material is useful for both the Windows programmer learning to build -Python extensions and the \UNIX{} programmer interested in producing -software which can be successfully built on both \UNIX{} and Windows. - -Module authors are encouraged to use the distutils approach for -building extension modules, instead of the one described in this -section. You will still need the C compiler that was used to build -Python; typically Microsoft Visual \Cpp. - -\begin{notice} - This chapter mentions a number of filenames that include an encoded - Python version number. These filenames are represented with the - version number shown as \samp{XY}; in practive, \character{X} will - be the major version number and \character{Y} will be the minor - version number of the Python release you're working with. For - example, if you are using Python 2.2.1, \samp{XY} will actually be - \samp{22}. -\end{notice} - - -\section{A Cookbook Approach \label{win-cookbook}} - -There are two approaches to building extension modules on Windows, -just as there are on \UNIX: use the -\ulink{\module{distutils}}{../lib/module-distutils.html} package to -control the build process, or do things manually. The distutils -approach works well for most extensions; documentation on using -\ulink{\module{distutils}}{../lib/module-distutils.html} to build and -package extension modules is available in -\citetitle[../dist/dist.html]{Distributing Python Modules}. This -section describes the manual approach to building Python extensions -written in C or \Cpp. - -To build extensions using these instructions, you need to have a copy -of the Python sources of the same version as your installed Python. -You will need Microsoft Visual \Cpp{} ``Developer Studio''; project -files are supplied for V\Cpp{} version 7.1, but you can use older -versions of V\Cpp. Notice that you should use the same version of -V\Cpp that was used to build Python itself. The example files -described here are distributed with the Python sources in the -\file{PC\textbackslash example_nt\textbackslash} directory. - -\begin{enumerate} - \item - \strong{Copy the example files}\\ - The \file{example_nt} directory is a subdirectory of the \file{PC} - directory, in order to keep all the PC-specific files under the - same directory in the source distribution. However, the - \file{example_nt} directory can't actually be used from this - location. You first need to copy or move it up one level, so that - \file{example_nt} is a sibling of the \file{PC} and \file{Include} - directories. Do all your work from within this new location. - - \item - \strong{Open the project}\\ - From V\Cpp, use the \menuselection{File \sub Open Solution} - dialog (not \menuselection{File \sub Open}!). Navigate to and - select the file \file{example.sln}, in the \emph{copy} of the - \file{example_nt} directory you made above. Click Open. - - \item - \strong{Build the example DLL}\\ - In order to check that everything is set up right, try building: - - \begin{enumerate} - \item - Select a configuration. This step is optional. Choose - \menuselection{Build \sub Configuration Manager \sub Active - Solution Configuration} and select either \guilabel{Release} - or\guilabel{Debug}. If you skip this step, - V\Cpp{} will use the Debug configuration by default. - - \item - Build the DLL. Choose \menuselection{Build \sub Build - Solution}. This creates all intermediate and result files in - a subdirectory called either \file{Debug} or \file{Release}, - depending on which configuration you selected in the preceding - step. - \end{enumerate} - - \item - \strong{Testing the debug-mode DLL}\\ - Once the Debug build has succeeded, bring up a DOS box, and change - to the \file{example_nt\textbackslash Debug} directory. You - should now be able to repeat the following session (\code{C>} is - the DOS prompt, \code{>>>} is the Python prompt; note that - build information and various debug output from Python may not - match this screen dump exactly): - -\begin{verbatim} -C>..\..\PCbuild\python_d -Adding parser accelerators ... -Done. -Python 2.2 (#28, Dec 19 2001, 23:26:37) [MSC 32 bit (Intel)] on win32 -Type "copyright", "credits" or "license" for more information. ->>> import example -[4897 refs] ->>> example.foo() -Hello, world -[4903 refs] ->>> -\end{verbatim} - - Congratulations! You've successfully built your first Python - extension module. - - \item - \strong{Creating your own project}\\ - Choose a name and create a directory for it. Copy your C sources - into it. Note that the module source file name does not - necessarily have to match the module name, but the name of the - initialization function should match the module name --- you can - only import a module \module{spam} if its initialization function - is called \cfunction{initspam()}, and it should call - \cfunction{Py_InitModule()} with the string \code{"spam"} as its - first argument (use the minimal \file{example.c} in this directory - as a guide). By convention, it lives in a file called - \file{spam.c} or \file{spammodule.c}. The output file should be - called \file{spam.dll} or \file{spam.pyd} (the latter is supported - to avoid confusion with a system library \file{spam.dll} to which - your module could be a Python interface) in Release mode, or - \file{spam_d.dll} or \file{spam_d.pyd} in Debug mode. - - Now your options are: - - \begin{enumerate} - \item Copy \file{example.sln} and \file{example.vcproj}, rename - them to \file{spam.*}, and edit them by hand, or - \item Create a brand new project; instructions are below. - \end{enumerate} - - In either case, copy \file{example_nt\textbackslash example.def} - to \file{spam\textbackslash spam.def}, and edit the new - \file{spam.def} so its second line contains the string - `\code{initspam}'. If you created a new project yourself, add the - file \file{spam.def} to the project now. (This is an annoying - little file with only two lines. An alternative approach is to - forget about the \file{.def} file, and add the option - \programopt{/export:initspam} somewhere to the Link settings, by - manually editing the setting in Project Properties dialog). - - \item - \strong{Creating a brand new project}\\ - Use the \menuselection{File \sub New \sub Project} dialog to - create a new Project Workspace. Select \guilabel{Visual C++ - Projects/Win32/ Win32 Project}, enter the name (\samp{spam}), and - make sure the Location is set to parent of the \file{spam} - directory you have created (which should be a direct subdirectory - of the Python build tree, a sibling of \file{Include} and - \file{PC}). Select Win32 as the platform (in my version, this is - the only choice). Make sure the Create new workspace radio button - is selected. Click OK. - - You should now create the file \file{spam.def} as instructed in - the previous section. Add the source files to the project, using - \menuselection{Project \sub Add Existing Item}. Set the pattern to - \code{*.*} and select both \file{spam.c} and \file{spam.def} and - click OK. (Inserting them one by one is fine too.) - - Now open the \menuselection{Project \sub spam properties} dialog. - You only need to change a few settings. Make sure \guilabel{All - Configurations} is selected from the \guilabel{Settings for:} - dropdown list. Select the C/\Cpp{} tab. Choose the General - category in the popup menu at the top. Type the following text in - the entry box labeled \guilabel{Additional Include Directories}: - -\begin{verbatim} -..\Include,..\PC -\end{verbatim} - - Then, choose the General category in the Linker tab, and enter - -\begin{verbatim} -..\PCbuild -\end{verbatim} - - in the text box labelled \guilabel{Additional library Directories}. - - Now you need to add some mode-specific settings: - - Select \guilabel{Release} in the \guilabel{Configuration} - dropdown list. Choose the \guilabel{Link} tab, choose the - \guilabel{Input} category, and append \code{pythonXY.lib} to the - list in the \guilabel{Additional Dependencies} box. - - Select \guilabel{Debug} in the \guilabel{Configuration} dropdown - list, and append \code{pythonXY_d.lib} to the list in the - \guilabel{Additional Dependencies} box. Then click the C/\Cpp{} - tab, select \guilabel{Code Generation}, and select - \guilabel{Multi-threaded Debug DLL} from the \guilabel{Runtime - library} dropdown list. - - Select \guilabel{Release} again from the \guilabel{Configuration} - dropdown list. Select \guilabel{Multi-threaded DLL} from the - \guilabel{Runtime library} dropdown list. -\end{enumerate} - - -If your module creates a new type, you may have trouble with this line: - -\begin{verbatim} - PyObject_HEAD_INIT(&PyType_Type) -\end{verbatim} - -Change it to: - -\begin{verbatim} - PyObject_HEAD_INIT(NULL) -\end{verbatim} - -and add the following to the module initialization function: - -\begin{verbatim} - MyObject_Type.ob_type = &PyType_Type; -\end{verbatim} - -Refer to section~3 of the -\citetitle[http://www.python.org/doc/FAQ.html]{Python FAQ} for details -on why you must do this. - - -\section{Differences Between \UNIX{} and Windows - \label{dynamic-linking}} -\sectionauthor{Chris Phoenix}{cphoenix@best.com} - - -\UNIX{} and Windows use completely different paradigms for run-time -loading of code. Before you try to build a module that can be -dynamically loaded, be aware of how your system works. - -In \UNIX, a shared object (\file{.so}) file contains code to be used by the -program, and also the names of functions and data that it expects to -find in the program. When the file is joined to the program, all -references to those functions and data in the file's code are changed -to point to the actual locations in the program where the functions -and data are placed in memory. This is basically a link operation. - -In Windows, a dynamic-link library (\file{.dll}) file has no dangling -references. Instead, an access to functions or data goes through a -lookup table. So the DLL code does not have to be fixed up at runtime -to refer to the program's memory; instead, the code already uses the -DLL's lookup table, and the lookup table is modified at runtime to -point to the functions and data. - -In \UNIX, there is only one type of library file (\file{.a}) which -contains code from several object files (\file{.o}). During the link -step to create a shared object file (\file{.so}), the linker may find -that it doesn't know where an identifier is defined. The linker will -look for it in the object files in the libraries; if it finds it, it -will include all the code from that object file. - -In Windows, there are two types of library, a static library and an -import library (both called \file{.lib}). A static library is like a -\UNIX{} \file{.a} file; it contains code to be included as necessary. -An import library is basically used only to reassure the linker that a -certain identifier is legal, and will be present in the program when -the DLL is loaded. So the linker uses the information from the -import library to build the lookup table for using identifiers that -are not included in the DLL. When an application or a DLL is linked, -an import library may be generated, which will need to be used for all -future DLLs that depend on the symbols in the application or DLL. - -Suppose you are building two dynamic-load modules, B and C, which should -share another block of code A. On \UNIX, you would \emph{not} pass -\file{A.a} to the linker for \file{B.so} and \file{C.so}; that would -cause it to be included twice, so that B and C would each have their -own copy. In Windows, building \file{A.dll} will also build -\file{A.lib}. You \emph{do} pass \file{A.lib} to the linker for B and -C. \file{A.lib} does not contain code; it just contains information -which will be used at runtime to access A's code. - -In Windows, using an import library is sort of like using \samp{import -spam}; it gives you access to spam's names, but does not create a -separate copy. On \UNIX, linking with a library is more like -\samp{from spam import *}; it does create a separate copy. - - -\section{Using DLLs in Practice \label{win-dlls}} -\sectionauthor{Chris Phoenix}{cphoenix@best.com} - -Windows Python is built in Microsoft Visual \Cpp; using other -compilers may or may not work (though Borland seems to). The rest of -this section is MSV\Cpp{} specific. - -When creating DLLs in Windows, you must pass \file{pythonXY.lib} to -the linker. To build two DLLs, spam and ni (which uses C functions -found in spam), you could use these commands: - -\begin{verbatim} -cl /LD /I/python/include spam.c ../libs/pythonXY.lib -cl /LD /I/python/include ni.c spam.lib ../libs/pythonXY.lib -\end{verbatim} - -The first command created three files: \file{spam.obj}, -\file{spam.dll} and \file{spam.lib}. \file{Spam.dll} does not contain -any Python functions (such as \cfunction{PyArg_ParseTuple()}), but it -does know how to find the Python code thanks to \file{pythonXY.lib}. - -The second command created \file{ni.dll} (and \file{.obj} and -\file{.lib}), which knows how to find the necessary functions from -spam, and also from the Python executable. - -Not every identifier is exported to the lookup table. If you want any -other modules (including Python) to be able to see your identifiers, -you have to say \samp{_declspec(dllexport)}, as in \samp{void -_declspec(dllexport) initspam(void)} or \samp{PyObject -_declspec(dllexport) *NiGetSpamData(void)}. - -Developer Studio will throw in a lot of import libraries that you do -not really need, adding about 100K to your executable. To get rid of -them, use the Project Settings dialog, Link tab, to specify -\emph{ignore default libraries}. Add the correct -\file{msvcrt\var{xx}.lib} to the list of libraries. |