將寫好的C程式變成Python的模組
 
現在的程式語言越來越方便,功能也越來越強大。直譯式的程式語言讓我們可以透過簡單的描述以及命令就能使電腦自動去處理資料,並得到你想要的結果。這類的語言如php, perl, python, ...等。通常這類的語言資料型態宣告十分鬆散,甚至不需要跟它講明資料型態,翻譯器會自動決定該變數所存放的資料。一般我們在撰寫C程式語言時凡是有使用到的變數都需要做型態宣告,如int表示整數型態,char表示字元型態,這些型態的宣告式方便編譯器向記憶體要一塊空間,提供變數暫存使用。一般來說,宣告成int表示會保留一塊連續的4bytes供該變數使用,char表示保留一塊連續的1bytes供該變數使用,當然設計者也可以自訂一些結構,用途也是保留一塊記憶體空間供該結構資料使用。python程式語言在編寫時,所有的變數皆不需給定型態,寫在等號左邊的資料就是變數,型態由右邊資料決定,這樣方便的寫作方式,讓程式開發的速度加速了。
 
想將你以前辛苦撰寫的程式變成python的模組來使用,使用import的方法將原有的舊程式寫成動態結檔,並解將它包入python程式中,有下列幾種方法。
 
一、使用SWIG
SWIG全名叫Simplified Wrapper and Interface Generator,它的功能可以將C或C++的程式碼自動的轉換,並產生接口,讓別的語言可以使用到原來程式的功能,該工具將C和C++的程式碼自動打包成動態連結檔(.dll)或靜態連結檔(.a),提供php, perl, python來使用。
 
這個工具因為功能十分強大,能自動轉換產生各種不同的script language所需的函式庫,所以很多人使用。而且在各種作業平台上都能使用,如果你是使用windows作業系統,而且懶得將原始碼重新編譯,請下載swigwin。如果你是使用unix或linux,請選擇swig
 
使用方式請參考:tutorial
大概的用法:首先如果是在Windows作業平台上,請下載swigwin,並解開該壓縮檔,取得swig.exe執行檔。
假設你所撰寫的C程式如下:   adder.c
 
int adder(int x, int y){
return x+y;
}
 
然後你必須產生一個介面檔(adder.i) ,該介面檔說明你將提供哪些函數供外部程式呼叫使用。
如下:

 %module math
 %{
 

extern int adder(int x, int y);
 

%}
 
接下來利用工具程式swig.exe幫你產生包裝檔,檔名為adder_warp.c
執行下面指令:     swig -pytho adder.i    後會自動產生 addr_warp.c
接著利用組譯工具(如VC 6, Dev-C, TC等)  將程式變成動態連結檔,得到math.dll
將該檔案複製到python的目錄中,執行python,import math
如果一切都沒有錯誤,將可以使用該模組的函式,如下
 
>>>  import math
>>>  math.adder(1,2)
>>>  3
 
 
二、使用Boost.Python
 
 
有時間再跟大家介紹
 
三、#include "python.h" 參考extend python中的說明,自己動手作
事實上,我的第一個dll檔是我參考python說明文件中的資料,將python模組從C語言延伸出來。事實上作法也相當簡單。使用編輯工具如:VC ++, Dev-C等,產生一個dll專案,並加入連接的入口,產生dll檔,複製到python安裝目錄,執行python即可使用。
 
math.c程式碼
 
#include "math.h"
 
 
下面綠色粗體的程式碼式dll專案自動產生的程式碼

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
          break;
      case DLL_PROCESS_DETACH:
          break;

      case DLL_THREAD_ATTACH:
          break;

      case DLL_THREAD_DETACH:
          break;
    }
    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}
下面區塊是描述提供的函數,就是你在math這個模組中所能提供呼叫使用的函數。
static PyMethodDef mathMethods[] = {
       {"adder", math_adder,METH_VARARGS},
       {"sub", math_sub,METH_VARARGS},
       {"mux", math_mux,METH_VARARGS},
       {NULL, NULL}
};
下面區塊所描述的是python的進入點。
//Python程式進入點
PyMODINIT_FUNC initmath(void)
{
     (void) Py_Initmath("math", mathMethods);
}
 
下面區塊是連接C程式與Python之間的接口
static PyObject *math_adder(PyObject *self, PyObject *args){
       int x, y, z;
       //取得外界參數
       if (!PyArg_ParseTuple(args, "i|i", &x,&y)) return NULL;
       //原本撰寫的C程式呼叫
       z = adder(x, y);
      return Py_BuildValue("i", z);
}
static PyObject *math_sub(PyObject *self, PyObject *args){
      int x, y, z;
       //取得外界參數
       if (!PyArg_ParseTuple(args, "i|i", &x,&y)) return NULL;
       //原本撰寫的C程式呼叫
       z = sub(x, y);
       return Py_BuildValue("i", z);
}
static PyObject *math_mux(PyObject *self, PyObject *args){
      int x, y, z;
       //取得外界參數
       if (!PyArg_ParseTuple(args, "i|i", &x,&y)) return NULL;
       //原本撰寫的C程式呼叫
       z = mux(x, y);
       return Py_BuildValue("i", z);
將上面的程式編譯成dll放到python安裝目錄下,即可執行。以上簡略說明。

    全站熱搜

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