只能说是实践,因为太简单。

这个实践的产生是由于中国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(&ltime);    return ctime(&ltime);    }
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则完全不用考虑这些问题。

更深入的主题应该多了解python文档中关于:

  • Extending and Embedding
  • Python/C API
  • Distributing Python Moules

还有就是SWIG方面的文档。

posted on 2013-05-10 11:23  一个人的天空@  阅读(2723)  评论(0编辑  收藏  举报