5.建置 Windows 上的 C 和 C++ 擴充

This chapter briefly explains how to create a Windows extension module forPython using Microsoft Visual C++, and follows with more detailed backgroundinformation on how it works. The explanatory material is useful for both theWindows programmer learning to build Python extensions and the Unix programmerinterested in producing software which can be successfully built on both Unixand Windows.

Module authors are encouraged to use the distutils approach for buildingextension modules, instead of the one described in this section. You will stillneed the C compiler that was used to build Python; typically Microsoft VisualC++.

備註

This chapter mentions a number of filenames that include an encoded Pythonversion number. These filenames are represented with the version number shownasXY; in practice,'X' will be the major version number and'Y'will be the minor version number of the Python release you're working with. Forexample, if you are using Python 2.2.1,XY will actually be22.

5.1.A Cookbook Approach

There are two approaches to building extension modules on Windows, just as thereare on Unix: use thesetuptools package to control the build process, ordo things manually. The setuptools approach works well for most extensions;documentation on usingsetuptools to build and package extension modulesis available in用 setuptools 建置 C 與 C++ 擴充套件. If you find you really need to dothings manually, it may be instructive to study the project file for thewinsound standard library module.

5.2.Differences Between Unix and Windows

Unix and Windows use completely different paradigms for run-time loading ofcode. Before you try to build a module that can be dynamically loaded, be awareof how your system works.

In Unix, a shared object (.so) file contains code to be used by theprogram, and also the names of functions and data that it expects to find in theprogram. When the file is joined to the program, all references to thosefunctions and data in the file's code are changed to point to the actuallocations in the program where the functions and data are placed in memory.This is basically a link operation.

In Windows, a dynamic-link library (.dll) file has no danglingreferences. Instead, an access to functions or data goes through a lookuptable. So the DLL code does not have to be fixed up at runtime to refer to theprogram's memory; instead, the code already uses the DLL's lookup table, and thelookup table is modified at runtime to point to the functions and data.

In Unix, there is only one type of library file (.a) which contains codefrom several object files (.o). During the link step to create a sharedobject file (.so), the linker may find that it doesn't know where anidentifier is defined. The linker will look for it in the object files in thelibraries; 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 importlibrary (both called.lib). A static library is like a Unix.afile; it contains code to be included as necessary. An import library isbasically 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 usesthe information from the import library to build the lookup table for usingidentifiers that are not included in the DLL. When an application or a DLL islinked, an import library may be generated, which will need to be used for allfuture DLLs that depend on the symbols in the application or DLL.

Suppose you are building two dynamic-load modules, B and C, which should shareanother block of code A. On Unix, you wouldnot passA.a to thelinker forB.so andC.so; that would cause it to be includedtwice, so that B and C would each have their own copy. In Windows, buildingA.dll will also buildA.lib. Youdo passA.lib to thelinker for B and C.A.lib does not contain code; it just containsinformation which will be used at runtime to access A's code.

In Windows, using an import library is sort of like usingimportspam; itgives you access to spam's names, but does not create a separate copy. On Unix,linking with a library is more likefromspamimport*; it does create aseparate copy.

5.3.Using DLLs in Practice

Windows Python is built in Microsoft Visual C++; using other compilers may ormay not work. The rest of this section is MSVC++ specific.

When creating DLLs in Windows, you must passpythonXY.lib to the linker.To build two DLLs, spam and ni (which uses C functions found in spam), you coulduse these commands:

cl/LD/I/python/includespam.c../libs/pythonXY.libcl/LD/I/python/includeni.cspam.lib../libs/pythonXY.lib

The first command created three files:spam.obj,spam.dll andspam.lib.Spam.dll does not contain any Python functions (suchasPyArg_ParseTuple()), but it does know how to find the Python codethanks topythonXY.lib.

The second command createdni.dll (and.obj and.lib),which knows how to find the necessary functions from spam, and also from thePython executable.

Not every identifier is exported to the lookup table. If you want any othermodules (including Python) to be able to see your identifiers, you have to say_declspec(dllexport), as invoid_declspec(dllexport)initspam(void) orPyObject_declspec(dllexport)*NiGetSpamData(void).

Developer Studio will throw in a lot of import libraries that you do not reallyneed, adding about 100K to your executable. To get rid of them, use the ProjectSettings dialog, Link tab, to specifyignore default libraries. Add thecorrectmsvcrtxx.lib to the list of libraries.