# 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.

初期化関数のシグネチャは次のとおりです:

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

1つの共有ライブラリに複数の初期化関数を定義することで、複数のモジュールをエクスポートすることは可能です。 しかし、デフォルトではファイル名に対応した関数しか見付けようとしないので、複数のモジュールをインポートさせるにはシンボリックリンクか独自のインポーターを使う必要があります。 詳しいことは PEP 489 の "Multiple modules in one library" 節を参照してください。

## 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.