Python:C語言擴充

來源:互聯網
上載者:User

標籤:

本文介紹如何用 C 語言來擴充 python。所舉的例子是,為 python 添加一個設定字串到 windows 的剪下板(Clipboard)的功能。我在寫以下代碼的時候用到的環境是:windows xp, gcc.exe 4.7.2, Python 3.2.3。

第一步 撰寫C語言的DLL

建立一個 clip.c 檔案,內容如下:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 // 設定 UNICODE 庫,這樣的話才可以正確複製寬字元集 #define UNICODE    #include <windows.h> #include <python.h>    // 設定文本到剪下板(Clipboard) static PyObject *setclip(PyObject *self, PyObject *args) {   LPTSTR  lptstrCopy;   HGLOBAL hglbCopy;   Py_UNICODE *content;   int len = 0;      // 將 python 的 UNICODE 字串及長度傳入   if (!PyArg_ParseTuple(args, "u#", &content, &len))     return NULL;      Py_INCREF(Py_None);      if (!OpenClipboard(NULL))     return Py_None;      EmptyClipboard();      hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len+1) * sizeof(Py_UNICODE));   if (hglbCopy == NULL) {     CloseClipboard();     return Py_None;   }      lptstrCopy = GlobalLock(hglbCopy);   memcpy(lptstrCopy, content, len * sizeof(Py_UNICODE));   lptstrCopy[len] = (Py_UNICODE) 0;      GlobalUnlock(hglbCopy);      SetClipboardData(CF_UNICODETEXT, hglbCopy);      CloseClipboard();      return Py_None; }    // 定義匯出給 python 的方法 static PyMethodDef ClipMethods[] = {   {"setclip", setclip, METH_VARARGS,    "Set string to clip."},   {NULL, NULL, 0, NULL} };    // 定義 python 的 model static struct PyModuleDef clipmodule = {   PyModuleDef_HEAD_INIT,   "clip",   NULL,   -1,   ClipMethods };    // 初始化 python model PyMODINIT_FUNC PyInit_clip(void) {   return PyModule_Create(&clipmodule); }

第二步 寫 python 的 setup.py

建立一個 setup.py 檔案,內容如下:

123456789 from distutils.core import setup, Extension    module1 = Extension(‘clip‘,                     sources = [‘clip.c‘])    setup (name = ‘clip‘,        version = ‘1.0‘,        description = ‘This is a clip package‘,        ext_modules = [module1])

第三步 用 python 編譯

運行以下命令:

python setup.py build --compiler=mingw32 install

在我的環境中會提示以下錯誤:

gcc: error: unrecognized command line option ‘-mno-cygwin‘

error: command ‘gcc‘ failed with exit status 1

開啟 %PYTHON安裝目錄%/Lib/distutils/cygwinccompiler.py 檔案,將裡面的 -mno-cygwin 刪除掉,然後再運行即可。

 

正常運行後,會產生一個 clip.pyd 檔案,並將該檔案複製到 %PYTHON安裝目錄%/Lib/site-packages 目錄中

 

第四步 測試該擴充

寫一個 test.py, 內容如下:

123 # -*- encoding: gbk -*- import clip clip.setclip("Hello python")

運行

python test.py

再到任何一個地方粘貼,即可驗證是否正確。

 

 

 

 

 

 

 

 

 

***************************************************************************************************
一個Python擴充模組是一個普通的C語言庫,對於UNIX電腦,這些庫通常以.so(表示共用對象)結尾。Python模組會把代碼分成3個部分:
(1)希望作為模組介面呈現的C函數;
(2)將Python開發人員所看到的那些函數的名稱映射為擴充模組中的C函數的一個表;
(3)初始化函數;

大多數擴充模組可以包含在一個單獨的C源檔案中,這個檔案被稱為膠水檔案,啟動包含Python.h的檔案,它允許訪問內部的Python
API,這些API將模組與解譯器相關聯。下面分別來講解上述的三個部分。
****************************************************************************************************
C函數簽名:
函數的C語言實現的簽名總是採用如下三個形式之一
(1)PyObject
*MyFunction(PyObject *self , PyObject *args);
(2)PyObject
*MyFunction(PyObject *self , PyObject *args , PyObject *kw);
(3)PyObject
*MyFunction(PyObject
*self);
通常,C函數會採用第一種形式,傳遞到這些函數中的參數被封裝成一個元組,為了使用這些參數,必須分解它們,可以使用PyArg_ParseTuple函數和PyArg_ParseTupleAndKeywords函數
PyArg_ParseTuple(args
, "ids" , &i , &d , &s)
將args分成int , double , char*,分別存入i , d ,
s
****************************************************************************************************
方法表:
方法表是PyMethodDef結構的一個簡單數組
struct
PyMethodDef
{
  char        
*ml_name;    #Python中使用的名字
  PyCFunction 
ml_meth;     #C函數的名字
 
int         
ml_flags;    #表示使用哪種C函數的簽名形式
 
char        
ml_doc;     
#函數的字串文檔
};
ml_flags向解譯器表明ml_meth正使用三個簽名中的哪一個。ml_flags的值通常是METH_VARARGS。如果希望將關鍵字參數引入到函數中,那麼這個值可以與METH_KEYWORDS按位或。它的值也可以是METH_NOARGS,表示不希望接受任何形式的參數。
下面是是一個例子,包含函數MyFunction的表:
static PyMethodDef myFunction[] = {
  {"pythonName" ,
(PyCFuntion)MyFunction , METH_NOARGS , "my first function"} ,
  { NULL ,
NULL , 0 ,
NULL}
};

****************************************************************************************************
初始化函數:
擴充模組的最後一部分是初始化函數。當模組被載入時,Python解譯器調用此函數。需要將函數命名為init模組名,例如initChenhuan,模組名為Chenhuan
****************************************************************************************************
下面是一個典型的C擴充模組:

個人比較喜歡用g++來編譯,error和warming區分的很清楚,格式如下:
g++ -Wall -shared -I /usr/local/python2.6 foo.c -o
foo.so

成功的話,會在檔案夾下產生foo.so,就可以使用這個模組了:

Python:C語言擴充

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.