4. 構建 C 和 C++ 擴充套件

CPython 的 C 擴充套件是一個共享庫(例如,Linux 上的 .so 檔案,Windows 上的 .pyd 檔案),它匯出一個初始化函式

為了可以匯入,該共享庫必須在 PYTHONPATH 上可用,並且必須以模組名命名,並帶有適當的副檔名。 當使用 setuptools 時,會自動生成正確的檔名。

初始化函式的簽名如下

PyObject *PyInit_modulename(void)

它返回一個完全初始化的模組,或者一個 PyModuleDef 例項。有關詳細資訊,請參閱初始化 C 模組

對於僅包含 ASCII 字元的模組名稱,該函式必須命名為 PyInit_<modulename>,其中 <modulename> 替換為模組的名稱。 當使用多階段初始化時,允許使用非 ASCII 模組名稱。 在這種情況下,初始化函式名稱為 PyInitU_<modulename>,其中 <modulename> 使用 Python 的 *punycode* 編碼進行編碼,並將連字元替換為下劃線。 在 Python 中

def initfunc_name(name):
    try:
        suffix = b'_' + name.encode('ascii')
    except UnicodeEncodeError:
        suffix = b'U_' + name.encode('punycode').replace(b'-', b'_')
    return b'PyInit' + suffix

透過定義多個初始化函式,可以從單個共享庫匯出多個模組。 但是,匯入它們需要使用符號連結或自定義匯入器,因為預設情況下只會找到與檔名對應的函式。 有關詳細資訊,請參閱 PEP 489 中的 “一個庫中的多個模組” 部分。

4.1. 使用 setuptools 構建 C 和 C++ 擴充套件

Python 3.12 及更高版本不再附帶 distutils。請參考 setuptools 的文件 https://setuptools.readthedocs.io/en/latest/setuptools.html,以瞭解更多關於如何使用 setuptools 構建和分發 C/C++ 擴充套件的資訊。