4. 构建 C 和 C++ 扩展¶
CPython 的 C 扩展是一个共享库(例如,Linux 上的 .so
文件,Windows 上的 .pyd
文件),它导出一个初始化函数。
为了可导入,共享库必须在 PYTHONPATH
上可用,并且必须以模块名称命名,并带有适当的扩展名。使用 setuptools 时,正确的文件名会自动生成。
初始化函数具有以下签名
它返回一个完全初始化的模块,或者一个 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++ 扩展的更多信息。