static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return Py_BuildValue("i", sts);
}
1.1 一個簡單的例子
讓我們創建一個名叫 "spam" (這是Python粉絲Monty喜愛的食物)的擴展模塊 ,我們打算創建一個Python接口,使用C庫函數 system().1.1 這個函數以一個空字符結尾(null-terminated)的字符串作爲參數,並返回一個整型數,我們想這個功能夠象下面這樣從Python調用:
>>> import spam >>> status = spam.system("ls -l")
首先創建文件 spammodule.c. (一般地,如果模塊名爲"spam", C它的實現文件名應爲 spammodule.c; 如果模塊名很長, 如"spammify", 模塊名可以爲 spammify.c ) .)
我們文件的第一行應爲:
#include <Python.h>
這樣就引入了Python API(如果你喜歡,可以增加描述模塊的目的和版權信息)。
除了那些定義在標準頭文件中的用戶可見的符號,其他所有在 Python.h文件中定義的用戶可見符號有 "Py" or "PY"前綴。 爲方便起見,也由於它們被Python解釋器廣泛使用,
"Python.h"
包含幾個標準頭文件 <stdio.h>
, <string.h>
,
<errno.h>
, and <stdlib.h>
。如果後幾個頭文件在你的系統上不存在,需要直接聲明malloc(), free() 和realloc() malloc(),
free() and realloc() 函數。
接着,我們繼續向模塊文件添加C函數,在Python表達式。 "spam.system(string) "被計算時,這個C函數將被調用:
這是從Python參數列表(如:單個表達式 "ls -l"
)到直接翻譯爲C函數參數。C函數總是有兩個參數,一般命名爲self 和 args 。
self參數只有當C函數實現內置方法使用,而實現函數時不使用。在本例中,由於我們定義的是一個函數而不是方法,self 總是一個NULL 指針(這樣做可以使解釋器不必關心兩種C函數的不同)。
args 參數是一個指向包含參數的Python元組對象指針。元組的每個條目對應於調用參數列表的一個參數。參數是Python對象――爲了在我們的C函數裏使用他們,我們必須把它們轉換爲C值。Python API函數PyArg_ParseTuple() 檢查參數類型並把它們轉換爲C值。它使用一個模板字符串來確定的參數類型和轉換後的值存入C變量的類型,後面詳述。
如果所有參數都是正確的類型,並且參數代表的各元素都被存儲到傳入地址的變量中,則PyArg_ParseTuple()函數返回爲true(非零)。 如果無效的參數被傳入,函數返回false(零)。在後面的例子中,PyArg_ParseTuple也產生一個恰當的異常,於是調用函數立刻返回 NULL (正如我們在例子中看到的)。