小結兩種在Python中匯入C語言擴充庫的方法

來源:互聯網
上載者:User

一種是Python文檔的推薦方案,採用C API擴充寫法:

在D:建一個add.c檔案,輸入

//add.c</p><p>//</p><p>#include <Python.h>;</p><p>static PyObject* add(PyObject *self, PyObject *args);<br />//一定聲明為static,把他們限制在這個檔案範圍裡。 幾乎所有的參數都是PyObject類型。 在python,每個東西都是object。 </p><p>static PyObject* add(PyObject* self, PyObject* args)<br />{<br /> int x=0 ;<br /> int y=0;<br /> int z=0;<br /> if (! PyArg_ParseTuple(args, "i|i", &x, &y))<br /> return NULL;<br /> /*第一個參數是self,這個是python用的, 每個函數都要有。我們暫時不管。args是一個參數列表。她把所有的參數都整合成一個string。所以<br /> 我們需要從這個string裡來解析我們的參數。PyArg_ParseTuple來完成這個任務。第一個參數是args, 就是我們要轉換的參數。第二個是格式符號。<br /> “s”代表是個string。 從args裡提取一個參數就寫"s", 兩個的話就寫"s|s", 如果是一個string,一個int,就寫"s|i", 和printf差不多。第三個<br /> 參數就是提取出來的參數放置的真正位置。必須傳遞這個參數的地址。對於add, 他將提取兩個參數。分別是x和y。*/<br />z=x+y;<br />return Py_BuildValue("i", z);<br /> /*調用完之後我們需要返回結果。這個結果是c的type或者是我們自己定義的類型。必須把他轉換成PyObject, 讓python認識。這個用Py_BuildValue<br /> 來完成。他是PyArg_ParseTuple的逆過程。他的第一個參數和PyArg_ParseTuple的第二個參數一樣, 是個格式化符號。第三個參數<br /> 是我們需要轉換的參數。Py_BuildValue會把所有的返回只組裝成一個tutple給python。*/<br />} </p><p>static PyMethodDef addMethods[] =<br />{<br /> {"add", add, METH_VARARGS, "Execute a shell command."},<br /> {NULL, NULL, 0, NULL}<br />};<br />/*這個是一個c的結構。他來完成一個映射。 我們需要把我們擴充的函數都映射到這個表裡。表的第一個欄位是python真正認識的。是python<br />裡的方法名字。 第二個欄位是python裡的這個方法名字的具體實現的函數名。 在python裡調用add, 真正執行的是用c寫的add函數。<br />第三個欄位是METH_VARARGS, 他告訴python,add是調用c函數來實現的。第四個欄位是這個函數的說明。如果你在python裡來help這個函數,<br />將顯示這個說明。相當於在python裡的函數的文檔說明。*/</p><p>PyMODINIT_FUNC initadd()<br />{<br /> Py_InitModule("add", addMethods);<br />}<br />/*注意,這個函數的名字不能改動。 必須是init+模組名字。 我們的模組名字是add。所以這個函數是initadd()。<br />這樣python在匯入add 的模組時候,才會找到這個函數,並調用。這個函數調用Py_InitModule來將模組名字和映射表結合在一起。<br />他表示,add這個模組使用addMethods這個映射表。python應該這樣匯入我們的module的.*/</p><p>

 

然後在D:盤建立setup.py

from distutils.core import setup, Extension</p><p>module1 = Extension('add', sources = ['add.c'])</p><p>setup (name = 'PackageName', version = '1.0', description = 'This is a ADD package', ext_modules = [module1])</p><p>

 

將cmd切換到D:

輸入setup.py build --compiler=mingw32 -verbose

這裡我選擇了mingw32,否則在我的機器上它會用msvc,而這會有一些小錯誤

運行成功後會在(目前的目錄的)D:/build/lib.win32-2.6下產生add.pyd

 

下面就在Python中匯入

>>> import sys
>>> sys.path.append("D:/build/lib.win32-2.6")

>>> import add
>>> add.add(3,2)
5

 

Bingo!

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

 

以上是用C API的擴充方式,它的寫法比較麻煩。以下用ctypes直接匯入dll模組。

 

如果是在Windows下面:

首先在D:建立檔案spam.c

//spam.c</p><p>//</p><p>#include <windows.h></p><p>BOOL APIENTRY<br />DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)<br />{<br /> return TRUE;<br />}</p><p>__declspec(dllexport) int<br />multiply(int num1, int num2)<br />{<br /> return num1 * num2;<br />}</p><p>//這是一個標準的Windows DLL的寫法。</p><p>

 

我用cl來編譯它,現在我漸漸喜歡上了用cl來編譯,省得建一個好幾兆的項目,而且參數可以靈活選擇。後面我會繼續學習如何寫make file。

在cmd輸入cl -I"d:/programs/python26/include" spam.cpp,會產生spam.obj

再輸入link spam.obj /DLL /libpath:"d:/programs/python26/libs",產生spam.dll

 

下面到python中匯入:

>>> import ctypes
>>> cdll=ctypes.cdll.LoadLibrary('d:/spam.dll')

>>> cdll.multiply(2,3)
6

 

如果是在Linux下面:

在/home/Henry下建立spam.c

char *foo(){<br /> char *p = "hello world";<br /> return p;<br />} </p><p>void foo1(char *p){<br /> strcpy(p, "hello world");<br />}<br />

編譯:$ gcc -o libspam.so -fpic -shared spam.c

進入Python:

#返回指標:<br />>>> import ctypes<br />>>> hello = ctypes.cdll.LoadLibrary("/home/Henry/libspam.so")<br />>>> p = hello.foo()<br />>>> ctypes.c_char_p(p).value<br />>>> 'hello world' </p><p>#傳入buffer:<br />>>> b = ctypes.create_string_buffer(12)<br />>>> hello.foo1(b)<br />>>> b.value<br />>>> 'hello world'<br />

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 

但是ctypes對C++的DLL匯入不行。對於C++庫的匯入還是要藉助於Boost.python。

我一定會回來的!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.