Python 與 C語言 PartII
 
這一次文章的內容完全以範例為主,而且我所使用的方法是直接將C程式語言擴展成為Python的模組。我不使用之前所提到的SWIG,也不使Boost.Python,理由很簡單,想要學習一樣東西從基本開始學,才能得心應手。
 
附註:事實上,因為我是使用DEV-C++(該工具不要錢,雖然最近也聽說微軟的程式開發工具也不用錢,但不知要去哪裡下載,所以使用DEV-C++)開發工具來製作我的動態執行檔,而不是使用微軟的IDE整合編譯環境Visual Stdio C++或2003,2005來開發,而DEV-C++是使用GCC來編譯資料,使用SWIG所產生的檔案(包裝檔 XXX_Warp.c)使用DEV-C++來編譯會產生一些錯誤,部分連結找不到(Linker not found),建議的解決方案是使用DEV-C++重新編譯python的python23.lib或python24.lib。使用Boost.Python也有同樣的問題。重新編譯python23.lib或python24.lib雖然不難,但是作程式的轉換要花到不少時間,所以就放棄使用工具程式。
 
接下來我先簡單的介紹一下工作環境與前置動作
 
首先當然得先下載python這個程式語言,目前最新的版本是V2.5(bata),或許你已經裝了比較舊版的python,那也沒關係。我測試的環境是(python V2.3和python V2.4),編譯起來都是正常可以執行的。你可以在安裝python的目錄下找到include的資料夾,裡面含有python.h後面會用到,請確認一下有沒有。另外在libs的資料夾下有python24.lib或python23.lib,,看你安裝Python的版本是哪一版來決定。如果是V2.5(bata)可能是python25.lib吧!我猜的,因為我沒裝過。
 
再來選擇你的開發環境,我的開發環境是DEV-C++,你可以到這裡下載,下載完將這個工具安裝在你的電腦上。
 
開發流程與範例
 
開啟DEV-C++這個工具程式,選擇檔案/開新檔案/專案,在Basic那個頁面下,選擇dll的圖示,並選擇C專案名稱欄位輸入你的專案名稱(如Math),然後按下確定並且存檔,之後會產生dll.c和dll.h兩個檔案。
 
再來設定專案所要用到的函式庫,請選擇專案/專案選項,在參數那個分頁中設定連結器的內容,方法:點選下面的按鈕新增函式庫或obj檔,選擇剛剛所提到的python23.lib或python24.lib的檔案,並將它開啟。然後到檔案/目錄的分頁中,選擇引入標頭檔目錄,將剛剛所提到的include那個資料夾加入。
 
你可以先將dll.c與dll.h檔案刪除,並加入下面的程式碼。
 
C語言程式碼
 
下面的程式是單純的C語言,包含Cmath.h和Cmath.c
Cmath.h的內容如下:
 
#ifndef _CMATH_H_
#define _CMATH_H_
int adder(int x, int y);
int sub(int x, int y);
int mux(int x, int y);

#endif
 
Cmath.c的內容如下:
#include "Cmath.h"
int adder(int x, int y)
{
    return x+y;   
}   
int sub(int x, int y)
{
    return x-y;   
}
   
int mux(int x, int y)
{
    return x*y;  
}
  
 
簡單說明一下:Cmath.c中包含三個函數,adder是作加法運算,sub是作減法運算,mux是作乘法運算,稍微懂一點C語言應該可以看的懂。現在我們要在python中提供一個Math的模組,該模組提供三個function分別作加、減和乘法運算,請注意該模組名稱Math的開頭第一個字M是大寫。接下來是撰寫接口程式。
 
Python的接口程式
 
接口程式包含math.h和mat.c兩個檔案
math.h的內容如下:
 
#ifndef _MATH_H_
#define _MATH_H_
#include "Python.h"
#include "Cmath.h"
# define DLLIMPORT __declspec (dllexport)
PyMODINIT_FUNC initMath();
static PyObject *Math_adder(PyObject *self, PyObject *args);
static PyObject *Math_sub(PyObject *self, PyObject *args);
static PyObject *Math_mux(PyObject *self, PyObject *args);

#endif
math.c的內容如下:
 
#include "math.h"
static PyMethodDef MathMethods[] = {
       {"adder", Math_adder,METH_VARARGS},
       {"sub", Math_sub,METH_VARARGS},
       {"mux", Math_mux,METH_VARARGS},
       {NULL, NULL}
};
//Python程式進入點
PyMODINIT_FUNC initMath()
{
     (void) Py_InitModule("Math", MathMethods);
}
//實作adder, sub, mux
static PyObject *Math_adder(PyObject *self, PyObject *args)
{
       int x, y, z;
       z = 0;
       //取得Pyhton參數            
       if (!PyArg_ParseTuple(args, "i|i", &x, &y)) return NULL;
       z = adder(x, y);
       return Py_BuildValue("i", z);
      
}
static PyObject *Math_sub(PyObject *self, PyObject *args)
{
       int x, y, z;
       z = 0;
       //取得Pyhton參數            
       if (!PyArg_ParseTuple(args, "i|i", &x, &y)) return NULL;
       z = sub(x, y);
       return Py_BuildValue("i", z);
}
static PyObject *Math_mux(PyObject *self, PyObject *args)
{
       int x, y, z;
       z = 0;
       //取得Pyhton參數            
       if (!PyArg_ParseTuple(args, "i|i", &x, &y)) return NULL;
       z = sub(x, y);
       return Py_BuildValue("i", z);      
}
      
 
編譯與測試
 
當你將上面四個檔案加入專案之後,選擇執行/編譯,過一陣子會產生Math.dll這個檔案。將這個檔案直接複製到python的安裝目錄,就可以使用。
 
使用方法:
>>> import Math
>>> Math.adder(5,3)
>>> 8
>>>
>>> Math.sub(5,2)
>>> 3
>>>
>>> Math.mux(2,5)
>>> 10
>>>
 
如果一切都順利,恭喜你,你成功了。
 

    全站熱搜

    CJY0503 發表在 痞客邦 留言(1) 人氣()