4. 建立 C 與 C++ 擴充套件
*************************

一個 CPython 的 C 擴充套件是一個共用函式庫（例如在 Linux 上的 ".so" 檔
案，在 Windows 上的 ".pyd"），會匯出一個*初始化函式*。

To be importable, the shared library must be available on
"PYTHONPATH", and must be named after the module name, with an
appropriate extension. When using setuptools, the correct filename is
generated automatically.

The initialization function has the signature:

PyObject *PyInit_modulename(void)

It returns either a fully initialized module, or a "PyModuleDef"
instance. See 初始化 C 模組 for details.

For modules with ASCII-only names, the function must be named
"PyInit_<modulename>", with "<modulename>" replaced by the name of the
module. When using Multi-phase initialization, non-ASCII module names
are allowed. In this case, the initialization function name is
"PyInitU_<modulename>", with "<modulename>" encoded using Python's
*punycode* encoding with hyphens replaced by underscores. In 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

It is possible to export multiple modules from a single shared library
by defining multiple initialization functions. However, importing them
requires using symbolic links or a custom importer, because by default
only the function corresponding to the filename is found. See the
*"Multiple modules in one library"* section in **PEP 489** for
details.


4.1. Building C and C++ Extensions with setuptools
==================================================

Python 3.12 and newer no longer come with distutils. Please refer to
the "setuptools" documentation at
https://setuptools.readthedocs.io/en/latest/setuptools.html to learn
more about how build and distribute C/C++ extensions with setuptools.
