5.在Windows构建C和C ++扩展

本章简要介绍如何使用Microsoft Visual C ++为Python创建Windows扩展模块,并详细介绍如何使用它的背景信息。解释性材料对于学习构建Python扩展的Windows程序员和能够在Unix和Windows上成功构建软件的Unix程序员都很有用.

鼓励模块作者使用distutils方法构建扩展模块,而不是本节中描述的那个。你仍然需要用于构建Python的C编译器;通常是Microsoft VisualC ++。

注意

本章提到了许多包含编码的Pythonversion编号的文件名。这些文件名用版本号表示XY;在实践中,"X"将是主要的版本号和"Y"将是您正在使用的Python版本的次要版本号。例如,如果你使用的是Python 2.2.1,XY实际上是22.

 

5.1。Cookbook方法

在Windows上构建扩展模块有两种方法,就像在Unix上一样:使用distutils包来控制构建过程,或者手动操作。distutils方法适用于大多数扩展;有关使用distutils构建和打包扩展模块的文档可在中分发Python模块(旧版本)。如果你发现你真的需要手动操作,研究winsound标准库模块的项目文件可能是有益的.

 

5.2。Unix和Windows之间的差异

Unix和Windows使用完全不同的范例来运行时加载代码。在尝试构建可动态加载的模块之前,请注意系统的工作方式.

在Unix中,共享对象(.so)文件包含程序使用的代码,以及它希望在程序中找到的函数和数据的名称。当文件加入程序时,文件代码中对这些函数和数据的所有引用都会更改为指向程序中的函数和数据放在内存中的实际分配。这基本上是一个链接操作.

在Windows中,动态链接库(.dll)文件没有悬空引用。相反,对函数或数据的访问通过查找表进行。因此,DLL代码不必在运行时修复以引用程序的内存;相反,代码已经使用了DLL的查找表,并且在运行时修改了查找表以指向函数和数据.

在Unix中,只有一种类型的库文件(.a)包含来自几个目标文件(.o)的代码。在链接步骤中创建共享对象文件(.so),链接器可能会发现它不知道anidentifier的定义位置。链接器将在库中的目标文件中查找它;如果找到它,它将包含该目标文件中的所有代码.

在Windows中,有两种类型的库,一个静态库和一个importlibrary(都叫.lib)。静态库就像Unix .a文件;它包含必要时包含的代码。导入库基本上仅用于向链接器确保某个标识符是合法的,并且在加载DLL时将出现在程序中。因此,链接器使用来自导入库的信息来为未包含在DLL中的usingidentifier构建查找表。当链接应用程序或DLL时,可能会生成导入库,这将需要用于依赖于应用程序或DLL中的符号的所有未来DLL .

假设你正在构建两个动态加载模块,B和C,它们应该共享另一个代码块A.在Unix上,你要notA.a传递给链接器B.soC.so;这将导致它被包含在内,因此B和C将各自拥有自己的副本。在Windows中,构建A.dll也将构建A.lib。你doA.lib传递给B和C的链接.A.lib不包含代码;它只包含将在运行时用于访问A代码的信息.

在Windows中,使用导入库有点像使用import spam;它允许您访问垃圾邮件的名称,但不会创建单独的副本。在Unix上,链接库更像是from spam import *;它确实创造了一个单独的副本.

 

5.3。在实践中使用DLL

Windows Python是用Microsoft Visual C ++构建的;使用其他编译器可能或不起作用(虽然Borland似乎)。本节的其余部分是MSVC ++特定的.

在Windows中创建DLL时,必须通过pythonXY.lib为了构建两个DLL,垃圾邮件和ni(使用垃圾邮件中的C函数),你可以使用这些命令:

cl /LD /I/python/include spam.c ../libs/pythonXY.lib
cl /LD /I/python/include ni.c spam.lib ../libs/pythonXY.lib

第一个命令创建了三个文件:spam.obj, spam.dllspam.lib. Spam.dll不包含任何Python函数(例如PyArg_ParseTuple()),但它确实知道如何找到Python codethanks pythonXY.lib.

第二个命令创建ni.dll(和.obj.lib),它知道如何从垃圾邮件中找到必要的函数,也从thePython可执行文件中找到它.

不是每个标识符都被导出到查找表中。如果你想让任何其他模块(包括Python)能够看到你的标识符,你必须说_declspec(dllexport),如void _declspec(dllexport) initspam(void)PyObject _declspec(dllexport) *NiGetSpamData(void).

Developer Studio会投入很多您真的不需要的导入库,为您的可执行文件添加大约100K。要删除它们,请使用“项目设置”对话框“链接”选项卡指定ignore default libraries。将正确的msvcrtxx.lib添加到图书馆列表中.

评论被关闭。