只能说是实践,因为太简单。
这个实践的产生是由于中国Linux论坛上一位rings的朋友的发贴。它提供了一个如何用C编写Python扩展模块的详细过程。[精华] 在windows上扩展python 。不过,那种方法要使用VC++环境,则我当时也没有。我有的环境是windows 98+cygwin,上面所提到的方法在我的环境下是无法成功的。因此我求助于google,找到一篇文章:
Python + Windows + distutils + SWIG + gcc MinGW or “Creating Python extensions in C/C++ with SWIG and compiling them with MinGW gcc under Windows” or “Installing Python extension with distutils and without Microsoft Visual C++”.
这篇文章详细介绍了如何不使用VC++环境,而只用MinGW环境去生成Python的扩展。于是忽我按照文中的方法正确地实现了。那么我简单地叙述一下在我的环境上的实现。
1.安装MinGW gcc
我早已安装了cygwin,因此上面已经带有gcc,这一步我就省略了。
2.生成libpython23.a
我的python版本是python 2.3.3。为什么要生成.a文件,因为gcc所用的库是.a格式的。安装完python后在dlls目录下会有一个pythonXX.lib的文件,它是VC++格式的库文件,gcc用不了。也就是说,Python本身是不带.a库的,需要我们自已生成。生成的方法按文中所说:
- 下载pexport。这里有一个更新一些的0.43版本。解压后有一个执行码放在你能在命令上找得到的地方就行了。我放在了cygwin/bin目录下了。
- 得到Python23.dll。为了工作方面,我建了一个工作目录,将dll拷贝到这个目录下。
- 进入命令行窗口。进不进入cygwin环境无所谓,因此我已经把cygwin/bin的目录加入到PATH中去了。
- 运行:pexports python23.dll >python23.def
- 运行:dlltool –dllname python23.dll –def python23.def –output-lib libpython23.a
- 将libpython23.a拷贝到python安装目录下的libs子目录中。其实拷不拷都无所谓,这样作只是为着以后再用方便。
这样.a库生成好了。
3.安装SWIG
SWIG在cygwin中已经存在了,如果没有可以从网上下载,一定要安装好。
4.创建一个扩展
example.c文件
/* File : example.c */
#include <time.h>double My_variable = 3.0;
int fact(int n) { if (n <= 1) return 1; else return n*fact(n-1); }
int my_mod(int x, int y) { return (x%y); }
char *get_time() { time_t ltime; time(<ime); return ctime(<ime); }
example.i文件内容
/* example.i */%module example%{/* Put header files here (optional) */%}
extern double My_variable;extern int fact(int n);extern int my_mod(int x, int y);extern char *get_time();
5.使用distutils编译扩展
python自带一个编译工具disutils。(原文讲述的disutils还有一些问题要手工改正,在我用的2.3.3中已经不存在了。)创建一个setup.py文件。
# setup.pyimport distutilsfrom distutils.core import setup, Extension setup(name = "Simple example from theSWIG website",version = "2.2",ext_modules = [Extension("_example", ["example.i","example.c"])])
然后运行:
Python setup.py build -cmingw32
这时候屏幕上会报一些警告,不用管它。完成后,你会在当前目录下看到一个example.py和一个_example.pyd的文件。
6.测试新的扩展
可以不用将生成的文件拷贝到python相应的目录下去,直接在当前目录下就可以测试。在命令行启动python,然后测试:
>>> import example
>>> example.fact(5)
120
>>> example.my_mod(7,3)
1
>>> example.get_time()
‘Mon Apr 12 15:46:27 2004\n’
>>>
成功。
rings介绍的方面是完全自已写一个扩展程序,要用到Python.h中定义的函数,结构。而使用SWIG则可以减少这方面的门槛,相对简单一些。更何况,用VC++编译成DLL也有些麻烦。而使用disutils则完全不用考虑这些问题。
•
Extending and Embedding
•
Python/C API
•
Python
Moules
还有就是SWIG方面的文档。