跳轉到內容

Python 程式設計/使用 C 擴充套件

來自華夏公益教科書,開放的書籍,開放的世界


Python 模組可以使用純 Python 編寫,也可以使用 C 語言編寫。以下展示瞭如何使用 C 擴充套件 Python。

使用 Python/C API

[編輯 | 編輯原始碼]

一個最小的例子

[編輯 | 編輯原始碼]

為了說明機制,我們將建立一個包含單個函式的最小擴充套件模組,該函式輸出 "Hello" 後跟作為第一個引數傳遞的名稱。

我們將首先建立 C 原始碼,並將其放置到 hellomodule.c

#include <Python.h>

static PyObject*
say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    printf("Hello %s!\n", name);

    Py_RETURN_NONE;
}

static PyMethodDef HelloMethods[] =
{
     {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
     {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inithello(void)
{
     (void) Py_InitModule("hello", HelloMethods);
}

然後我們需要一個安裝檔案,setup.py

from distutils.core import setup, Extension

module1 = Extension('hello', sources = ['hellomodule.c'])

setup (name = 'PackageName',
        version = '1.0',
        description = 'This is a demo package',
        ext_modules = [module1])

然後我們可以使用一個過程來構建模組,該過程的詳細資訊取決於作業系統和編譯器套件。

使用 GCC 在 Linux 上構建

[編輯 | 編輯原始碼]

在編譯模組之前,您必須安裝 Python 開發標頭檔案,如果您還沒有安裝的話。在 Debian 和基於 Debian 的系統(如 Ubuntu)上,可以使用以下命令安裝這些標頭檔案

$ sudo apt install python-dev

在 openSUSE 上,所需軟體包名為 python-devel,可以使用 zypper 安裝

$ sudo zypper install python-devel


現在 Python.h 可用了,我們可以使用以下命令編譯上一節中建立的模組原始碼

$ python setup.py build

這將編譯模組到名為hello.so的檔案中,位於build/lib.linux-i686-x.y.

使用 GCC 在 Microsoft Windows 上構建

[編輯 | 編輯原始碼]

Microsoft Windows 使用者可以使用 MinGW 從命令列編譯擴充套件模組。假設gcc在路徑中,您可以使用以下命令構建擴充套件

python setup.py build -cmingw32

以上將生成檔案hello.pyd,一個 Python 動態模組,類似於 DLL。該檔案將位於build\lib.win32-x.y.

在 Windows 中構建模組的另一種方法是構建一個 DLL。(這種方法不需要擴充套件模組檔案)。從cmd.exe,輸入

gcc -c  hellomodule.c -I/PythonXY/include
gcc -shared hellomodule.o -L/PythonXY/libs -lpythonXY -o hello.dll

其中 XY 表示 Python 的版本,例如 "24" 表示 2.4 版。

使用 Microsoft Visual C++ 構建

[編輯 | 編輯原始碼]

對於 VC8,distutils 出現了問題。因此,我們將使用命令提示符中的 cl.exe

cl /LD hellomodule.c /Ic:\Python24\include c:\Python24\libs\python24.lib /link/out:hello.dll

使用擴充套件模組

[編輯 | 編輯原始碼]

切換到 hello.so 檔案所在的子目錄。在互動式 Python 會話中,您可以按如下方式使用該模組。

>>> import hello
>>> hello.say_hello("World")
Hello World!

用於計算斐波那契數列的模組

[編輯 | 編輯原始碼]

在本節中,我們將介紹一個用於斐波那契數列的模組,從而擴充套件了上面的最小示例。與最小示例相比,值得注意的是在 PyArg_ParseTuple() 和 Py_BuildValue() 中使用了 "i"。

C 原始碼(fibmodule.c)

#include <Python.h>

int
_fib(int n)
{
    if (n < 2)
        return n;
    else
        return _fib(n-1) + _fib(n-2);
}

static PyObject*
fib(PyObject* self, PyObject* args)
{
    int n;

    if (!PyArg_ParseTuple(args, "i", &n))
        return NULL;

    return Py_BuildValue("i", _fib(n));
}

static PyMethodDef FibMethods[] = {
    {"fib", fib, METH_VARARGS, "Calculate the Fibonacci numbers."},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initfib(void)
{
    (void) Py_InitModule("fib", FibMethods);
}

構建指令碼(setup.py)

from distutils.core import setup, Extension

module1 = Extension('fib', sources = ['fibmodule.c'])

setup (name = 'PackageName',
        version = '1.0',
        description = 'This is a demo package',
        ext_modules = [module1])

使用

>>> import fib
>>> fib.fib(10)
55

使用 SWIG

[編輯 | 編輯原始碼]

SWIG 是一個工具,可以幫助各種指令碼和程式語言呼叫 C 和 C++ 程式碼。SWIG 使得建立 C 語言模組變得更加直接。

要使用 SWIG,您需要先將其啟動並執行。

您可以在 Ubuntu 系統上按如下方式安裝它

$ sudo apt-get install swig
$ sudo apt-get install python-dev

要獲取適用於 Windows 的 SWIG,您可以使用 SWIG 下載頁面提供的二進位制檔案。

安裝完 SWIG 後,您需要建立模組原始檔和模組介面檔案

hellomodule.c

#include <stdio.h>

void say_hello(const char* name) {
    printf("Hello %s!\n", name);
}

hello.i

%module hello
extern void say_hello(const char* name);

然後我們讓 SWIG 完成它的工作

swig -python hello.i

以上會生成檔案 hello.py 和 hello_wrap.c。

下一步是編譯;將 /usr/include/python2.4/ 替換為您設定中 Python.h 的正確路徑

gcc -fpic -c hellomodule.c hello_wrap.c -I/usr/include/python2.4/

最後一步是連結

gcc -shared hellomodule.o hello_wrap.o -o _hello.so -lpython

模組的使用方法如下

>>> import hello
>>> hello.say_hello("World")
Hello World!
[編輯 | 編輯原始碼]
華夏公益教科書