`
luliangok
  • 浏览: 771319 次
文章分类
社区版块
存档分类
最新评论

(Python编程)一个简单的C扩展模块

 
阅读更多

Programming Python, 3rd Edition 翻译
最新版本见:http://wiki.woodpecker.org.cn/moin/PP3eD

22.4. A Simple C Extension Module

22.4. 一个简单的C扩展模块

At least that's the short story; we need to turn to some code to make this more concrete. C types generally export a C module with a constructor function. Because of that, and because they are simpler, let's start off by studying the basics of C module coding with a quick example.

简短的概览之后,我们需要用代码来更具体地展示C扩展。C类型一般导出一个C模块,其中有一个构造函数。那样很简单,因此,让我们用一个简例从编写C模块的基础开始学习。

As mentioned, when you add new or existing C components to Python, you need to code an interface ("glue") logic layer in C that handles cross-language dispatching and data translation. The C source file in Example 22-1 shows how to code one by hand. It implements a simple C extension module named hello for use in Python scripts, with a function named message that simply returns its input string argument with extra text prepended. Python scripts will call this function as usual, but this one is coded in C, not in Python.

如前所述,当你向Python添加新的或已有的C部件,你需要用C编写接口逻辑层(粘合层),来处理语言间的分派和数据翻译。例22-1的C语言源文件显示了如何对此进行手工编码。它实现了一个简单的C扩展模块hello,有一个函数message,简单地对输入串添加一些文本并返回,它可在Python脚本中使用。Python脚本像通常那样调用这个函数,但这个函数是用C写的,而不是Python.

Example 22-1. PP3E/Integrate/Extend/Hello/hello.c
/**//********************************************************************
*AsimpleCextensionmoduleforPython,called"hello";compile
*thisintoa".so"onpythonpath,importandcallhello.message;
*******************************************************************
*/


#include
<Python.h>
#include
<string.h>

/**//*modulefunctions*/
staticPyObject*/**//*returnsobject*/
message(PyObject
*self,PyObject*args)/**//*selfunusedinmodules*/
...{/**//*argsfromPythoncall*/
char*fromPython,result[64];
if(!PyArg_Parse(args,"(s)",&fromPython))/**//*convertPython->C*/
returnNULL;/**//*null=raiseexception*/
else...{
strcpy(result,
"Hello,");/**//*buildupCstring*/
strcat(result,fromPython);
/**//*addpassedPythonstring*/
returnPy_BuildValue("s",result);/**//*convertC->Python*/
}

}


/**//*registrationtable*/
staticstructPyMethodDefhello_methods[]=...{
...{"message",message,1},/**//*methodname,Cfuncptr,always-tuple*/
...{NULL,NULL}/**//*endoftablemarker*/
}
;

/**//*moduleinitializer*/
voidinithello()/**//*calledonfirstimport*/
...{/**//*namemattersifloadeddynamically*/
(
void)Py_InitModule("hello",hello_methods);/**//*modname,tableptr*/
}



Ultimately, Python code will call this C file's message function, passing in a string object and getting back a new string object. First, though, it has to be somehow linked into the Python interpreter. To use this C file in a Python script, compile it into a dynamically loadable object file (e.g., hello.so on Linux, hello.dll under Cygwin on Windows) with a makefile like the one listed in Example 22-2, and drop the resulting object file into a directory listed on your module import search path exactly as though it were a .py or .pyc file.

最终Python代码将调用这个C文件中的message函数,传入一个字符串对象并返回一个新的字符串对象。但是,它首先必须以某种方式连接到Python解释器。为了在Python脚本中使用这个C文件,可使用类似例22-2所列的make文件,将它编译成动态装载的目标文件(例如,Linux上的hello.so,Windows上的Cygwin下的hello.dll),并将结果目标文件放入你的导入模块搜索路径,就像它是一个.py或.pyc文件。

Example 22-2. PP3E/Integrate/Extend/Hello/makefile.hello
#############################################################
# Compile hello.c into a shareable object file on Cygwin,
# to be loaded dynamically when first imported by Python.
#############################################################

PYLIB = /usr/bin
PYINC = /usr/include/python2.4

hello.dll: hello.c
gcc hello.c -g -I$(PYINC) -shared -L$(PYLIB) -lpython2.4 -o hello.dll

clean:
rm -f hello.dll core



This is a Cygwin makefile that uses gcc to compile our C code; other platforms are analogous but will vary. As mentioned in Chapter 5 in the sidebar "Forking on Windows with Cygwin," Cygwin provides a Unix-like environment and libraries on Windows. To work along with the examples here, either see http://www.cygwin.com for download details or change the makefiles listed per your compiler and platform requirements. Be sure to include the path to Python's install directory with -I flags to access Python include (a.k.a. header) files, as well as the path to the Python binary library file with -L flags, if needed.

这是一个Cygwin make文件,用gcc作编译器;在其它平台会有不同,但是类似。在第5章的补充栏“在Windows上用Cygwin来分支进程”中提过,Cygwin在Windows上提供了一个类Unix的环境和库。要让这里的例子工作,要么查看http://www.cygwin.com上的下载详情,要么按你的平台和编译器的要求更改make文件。注意要用-I参数包含Python的安装路径,这样才能找到Python包含文件,也叫头文件,必要时还要用-L参数指出Python的二进制库文件的路径。

Now, to use the makefile in Example 22-2 to build the extension module in Example 22-1, simply type a standard make command at your shell (the Cygwin shell is used here):

现在,在你的shell界面简单地敲入标准make命令,用例22-2的make文件来构建例22-1的扩展模块,本例中使用的是Cygwin shell:

.../PP3E/Integrate/Extend/Hello$ make -f makefile.hello
gcc hello.c -g -I/usr/include/python2.4 -shared
-L/usr/bin -lpython2.4 -o hello.dll



This generates a shareable object filea .dll under Cygwin on Windows. When compiled this way, Python automatically loads and links the C module when it is first imported by a Python script. At import time, the .dll binary library file will be located in a directory on the Python import search path, just like a .py file. Because Python always searches the current working directory on imports, this chapter's examples will run from the directory you compile them in (.) without any file copies or moves. In larger systems, you will generally place compiled extensions in a directory listed in PYTHONPATH or .pth files instead.

这样会生成一个共享目标文件,在Windows的Cygwin上是一个.dll文件。这样编译后,Python会在脚本第一次导入时,自动装载和链接这个C模块。当导入时,将会在Python的导入搜索路径中查找该.dll二进制库文件,就像一个.py文件。因为Python导入时总是搜索当前工作目录,本章的例子将不进行复制或称动,而是在你编译的当前目录(.)下运行。而在大型系统中,你一般会将编译的扩展模块放在PYTHONPATH或.pth文件所列目录下。

Finally, to call the C function from a Python program, simply import the module hello and call its hello.message function with a string; you'll get back a normal Python string:

最后,在Python程序中调用C函数,只需导入hello模块并调用hello.message函数;你将得到一个Python串返回值。

.../PP3E/Integrate/Extend/Hello$ python
>>> import hello # import a C module
>>> hello.message('world') # call a C function
'Hello, world'
>>> hello.message('extending')
'Hello, extending'



And that's ityou've just called an integrated C module's function from Python. The most important thing to notice here is that the C function looks exactly as if it were coded in Python. Python callers send and receive normal string objects from the call; the Python interpreter handles routing calls to the C function, and the C function itself handles Python/C data conversion chores.

这就成了,你刚才已经在Python中调用了一个集成的C模块的函数。着重要注意的是,这里C函数看起来完全像是用Python编写的。Python调用者传入和接收了一个普通的字符串对象;Python解译器将调用发送给C函数,C函数本身处理了Python/C的数据转换。

In fact, there is little to distinguish hello as a C extension module at all, apart from its filename. Python code imports the module and fetches its attributes as if it had been written in Python. C extension modules even respond to dir calls as usual and have the standard module and filename attributes (though the filename doesn't end in a .py or .pyc this time around):

实际上,除了文件名之外,很难分辨出hello是一个C扩展模块。Python代码导入模块并获取它的属性,就像它是Python写的一样。C扩展模块甚至像通常那样响应dir调用,并有标准的模块和文件名属性(尽管这里的文件名不是.py或.pyc结尾)。

>>> dir(hello) # C module attributes
['_ _doc_ _', '_ _file_ _', '_ _name_ _', 'message']

>>> hello._ _name_ _, hello._ _file_ _
('hello', 'hello.dll')

>>> hello.message # a C function object
<built-in function message>
>>> hello # a C module object
<module 'hello' from 'hello.dll'>



Like any module in Python, you can also access the C extension from a script file. The Python file in Example 22-3, for instance, imports and uses the C extension module.

你也可以在脚本文件中像Python模块一样使用C扩展模块。例22-3的Python文件导入并使用了C扩展模块。

Example 22-3. PP3E/Integrate/Extend/Hello/hellouse.py
importhello

printhello.message('C')
printhello.message('module'+hello.__file__)

foriinrange(3):
printhello.message(str(i))


Run this script as any otherwhen the script first imports the module hello, Python automatically finds the C module's .dll object file in a directory on the module search path and links it into the process dynamically. All of this script's output represents strings returned from the C function in the file hello.c:

像其它脚本那样运行这个脚本。当第一次导入模块hello时,Python自动在模块搜索路径中找到C模块的.dll目标文件,并将它动态链接到进程内。脚本的输出就是hello.c文件的C函数的返回串。

.../PP3E/Integrate/Extend/Hello$ python hellouse.py
Hello, C
Hello, module /cygdrive/c/.../PP3E/Integrate/Extend/Hello/hello.dll
Hello, 0
Hello, 1
Hello, 2


分享到:
评论

相关推荐

    Python 编程入门经典

    《Python编程入门经典》(作者James Payne)主要介绍Python 3.1。Python 3.1发布于2009年,是Python程序语言的最新主版本。由于Python是一门跨平台的语言,本书中的内容和示例适用于任何平台(除非特别指出的例外情况)...

    Python编程入门经典高清中文版.pdf

    第10章 创建模块 第Ⅲ部分 开始使用Python 第12章 测试 第13章 使用 Python编写GUI 第14章 访问数据库 第15章 使用Python处理XML 第16章 网络编程 第17章 用C扩展编程 第18章 数值编程 第19章 Django简介 第20章 Web...

    Python编程入门经典

    12.4.2 一个更加强大的Python 搜索 207 12.5 软件生命周期中的正规 测试 210 12.6 本章小结 210 第13章 使用Python编写GUI 213 13.1 Python的GUI编程工具箱 213 13.2 Tkinter简介 215 13.3 用Tkinter创建GUI 小组件 ...

    《Python入门经典以解决计算问题为导向的Python编程实践》.((美)William F).[PDF]@ckook.pdf

    介绍Jython的内部机理,Jython是一个用Java编写的Python版本。 Python入门经典目录 第一部分关于计算机的思考 第0章计算机科学研究 第二部分开始编程 第1章入门 第2章控制语句 第3章算法和程序开发 第三部分...

    Python编程语言设计开发的C语言学习及考试信息管理系统.zip

    Python编程语言是一种高级、解释型、面向对象的编程语言。它有许多特点,其中最突出的是简洁易读的语法,这使得它易于学习和使用。Python的语法非常清晰和简单,使用者可以很容易地理解代码的含义,减少编写代码时...

    python计算机视觉编程

    5.1.1 一个简单的数据集 5.1.2 用matplotlib绘制三维数据 5.1.3 计算f:八点法 5.1.4 外极点和外极线 5.2 照相机和三维结构的计算 5.2.1 三角剖分 5.2.2 由三维点计算照相机矩阵 5.2.3 由基础矩阵...

    Python官方文档网页版方便查看

    Python 是一种简单易学且功能强大的编程语言。它具有高效且高层次的数据结构和简单有效面向对象编程方法。Python优雅的语法和动态编辑,和它的解释特性一起,使其在绝大多数平台的许多领域成为理想的编写和快速应用...

    Python 2.5

    Python是一个有10年历史的Windows编程语言。Python的创始人为Guido van Rossum。 &lt;br/&gt; &lt;br/&gt;Python是一种即译式的,互动的,面向对象的编程语言,它包含了模组式的操作,异常处理,动态资料形态,十分高...

    Python核心编程第二版(ok)

     2.19.2 如何访问一个模块函数或访问一个模块变量   2.20 实用的函数   2.21 练习   第3章 Python基础   3.1 语句和语法   3.1.1 注释(#)   3.1.2 继续()   3.1.3 多个语句构成代码组...

    Python3.6+中文文档.pdf

    Python 中许多最引人瞩目的特性,并且会给你一个关于语言特色和风格的认识。读完之后,你将能够阅读 和编写 Python 模块或程序,并为以后使用 Python 参考手册 继续学习诸多 Python 模块库做好准备。

    Python 模块-模块名也是一个标识符

    Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器...

    Python 模块-使用模块演练

    Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器...

    python编程-谭祖意

    常见的一种应用情形是,使用Python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中有特别要求的部分,用更合适的语言改写,比如3D游戏中的图形渲染模块,性能要求特别高,就可以用C/C++重写,而后封装...

    python-3.11.2-docs.epub Python学习资料 Python文档

    Python 解释器易于扩展,使用 C 或 C++(或其他 C 能调用的语言)即可为 Python 扩展新功能和数据类型。Python 也可用作定制软件中的扩展程序语言。 本教程只是简单介绍了 Python 语言概念和功能。读者在阅读本教程...

    python官方文档(中文版)

    最好在阅读的时候准备一个 Python 解释器进行练习,不过所有的例子都是相互独立的,所以这个教程也可以离线阅读。 有关标准的对象和模块,参阅 Python 标准库。Python 语言参考 提供了更正式的语言参考。想要编写 C...

    Python 模块-概念介绍

    Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器...

    python3.6.0入门指南(官方版)

    虽然你能够使用 C/C++/JAVA 编写程序,但即使编写一个简单的 first-draft 程序也有可能耗费 大量的开发时间。相比之下, Python 更易于使用,无论在 Windows 、 Mac OS X 或 Unix 操作系统上它都会帮助你更快地完成...

    Windows平台Python编程必会模块之pywin32介绍

    要完成这一目标,有两种办法,一种是使用C编写Python扩展模块,或者就是编写普通的DLL通过python的ctypes来调用,但是这样就部分牺牲掉了Python的快速开发、免编译特性。 还好,有一个模块pywin32可以解决这个问题,...

    python-计算机-python 是什么-python有什么用-python的使用场景有哪些-python的发展前景

    关于python python 是什么,python有什么用,python的...可扩展性:Python可以通过C/C++编写的扩展模块进行性能优化,同时也可以与其他语言进行集成。 丰富的社区支持:Python拥有庞大的开源社区,提供了大量的文档

Global site tag (gtag.js) - Google Analytics