只能說是實踐,因為太簡單。
這個實踐的產生是由於中國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則完全不用考慮這些問題。
更深入的主題應該多瞭解python文檔中關於:
- Extending and Embedding
- Python/C API
- Distributing Python Moules
還有就是SWIG方面的文檔。