1. C や C++ による Python の拡張
********************************

C プログラムの書き方を知っているなら、Python に新たな組み込みモジュー
ルを追加するのはきわめて簡単です。この新たなモジュール、拡張モジュール
(*extension module*) を使うと、Python が直接行えない二つのこと: 新しい
組み込みオブジェクトの実装、そして全ての C ライブラリ関数とシステムコ
ールに対する呼び出し、ができるようになります。

拡張モジュールをサポートするため、Python API (Application Programmer's
Interface) では一連の関数、マクロおよび変数を提供していて、Python ラン
タイムシステムのほとんどの側面へのアクセス手段を提供しています。
Python API は、ヘッダ ""Python.h"" をインクルードして C ソースに取り込
みます。

拡張モジュールのコンパイル方法は、モジュールの用途やシステムの設定方法
に依存します。詳細は後の章で説明します。

注釈:

  C 拡張のインターフェイスは CPython に固有のものであり、これによる拡
  張モジュールはほかの Python 実装では動作しません。多くの場合、C 拡張
  を書くことを避けてほかの Python 実装のために移植性を確保することは可
  能です。たとえば、あなたがしたいことが C ライブラリの関数やシステム
  コールを呼び出すことである場合、 "ctypes" あるいは cffi ライブラリの
  利用を検討すべきです。これらのモジュールは C コードとインターフェイ
  スし、C 拡張を書いてコンパイルするのに較べて Python 実装間のより高い
  移植性をもった Python コードを書かせてくれます。


1.1. 簡単な例
=============

"spam" (Monty Python ファンの好物ですね) という名の拡張モジュールを作
成することにして、C ライブラリ関数 "system()" に対する Python インター
フェイスを作成したいとします。 [1] この関数は null で終端されたキャラ
クタ文字列を引数にとり、整数を返します。この関数を以下のようにして
Python から呼び出せるようにしたいとします。

   >>> import spam
   >>> status = spam.system("ls -l")

まずは "spammodule.c" を作成するところから始めます。 (伝統として、
"spam" という名前のモジュールを作成する場合、モジュールの実装が入った
C ファイルを "spammodule.c" と呼ぶことになっています; "spammify" のよ
うに長すぎるモジュール名の場合には、単に "spammify.c" にもできます。)

このファイルの最初の 2 行は以下のようにします:

   #define PY_SSIZE_T_CLEAN
   #include <Python.h>

これで、Python API を取り込みます (必要なら、モジュールの用途に関する
説明や、著作権表示を追加します)。

注釈:

  Python は、システムによっては標準ヘッダの定義に影響するようなプリプ
  ロセッサ定義を行っているので、 "Python.h" をいずれの標準ヘッダよりも
  前にインクルード *せねばなりません* 。"#define PY_SSIZE_T_CLEAN" は
  、いくつかの API では "int" の代わりに "Py_ssize_t" が使われるべきで
  あることを示すために使われていました。これは Python 3.13 以降では不
  要となりましたが、後方互換性のために維持されています。このマクロの説
  明は 文字列とバッファ にあります。

"Python.h" で定義されているユーザから可視のシンボルは、全て接頭辞 "Py"
または "PY" が付いています。ただし、標準ヘッダファイル内の定義は除きま
す。簡単のためと、Python 内で広範に使うことになるという理由から、
""Python.h"" はいくつかの標準ヘッダファイル: "<stdio.h>" 、
"<string.h>" 、 "<errno.h>" 、および "<stdlib.h>" をインクルードしてい
ます。後者のヘッダファイルがシステム上になければ、 ""Python.h"" が関数
"malloc()" 、 "free()" および "realloc()" を直接定義します。

次にファイルに追加する内容は、Python 式 "spam.system(string)" を評価す
る際に呼び出されることになる C 関数です (この関数を最終的にどのように
呼び出すかは、後ですぐわかります):

   static PyObject *
   spam_system(PyObject *self, PyObject *args)
   {
       const char *command;
       int sts;

       if (!PyArg_ParseTuple(args, "s", &command))
           return NULL;
       sts = system(command);
       return PyLong_FromLong(sts);
   }

ここでは、Python の引数リスト (例えば、単一の式 ""ls -l"") から C 関数
に渡す引数にそのまま変換しています。 C 関数は常に二つの引数を持ち、便
宜的に *self* および *args* と呼ばれます。

*self* 引数には、モジュールレベルの関数であればモジュールが、メソッド
にはオブジェクトインスタンスが渡されます。

*args* 引数は、引数の入った Python タプルオブジェクトへのポインタにな
ります。タプル内の各要素は、呼び出しの際の引数リストにおける各引数に対
応します。引数は Python オブジェクトです --- C 関数で引数を使って何か
を行うには、オブジェクトから C の値に変換せねばなりません。Python API
の関数 "PyArg_ParseTuple()" は引数の型をチェックし、C の値に変換します
。 "PyArg_ParseTuple()" はテンプレート文字列を使って、引数オブジェクト
の型と、変換された値を入れる C 変数の型を判別します。これについては後
で詳しく説明します。

"PyArg_ParseTuple()" は、全ての引数が正しい型を持っていて、アドレス渡
しされた各変数に各引数要素を保存したときに真 (非ゼロ) を返します。この
関数は不正な引数リストを渡すと偽 (ゼロ) を返します。後者の場合、関数は
適切な例外を送出するので、呼び出し側は (例にもあるように) すぐに
"NULL" を返すようにしてください。


1.2. 幕間小話: エラーと例外
===========================

An important convention throughout the Python interpreter is the
following: when a function fails, it should set an exception condition
and return an error value (usually "-1" or a "NULL" pointer).
Exception information is stored in three members of the interpreter's
thread state.  These are "NULL" if there is no exception.  Otherwise
they are the C equivalents of the members of the Python tuple returned
by "sys.exc_info()".  These are the exception type, exception
instance, and a traceback object.  It is important to know about them
to understand how errors are passed around.

Python API では、様々な型の例外をセットするための関数をいくつか定義し
ています。

もっともよく用いられるのは "PyErr_SetString()" です。引数は例外オブジ
ェクトと C 文字列です。例外オブジェクトは通常、
"PyExc_ZeroDivisionError" のような定義済みのオブジェクトです。 C 文字
列はエラーの原因を示し、Python 文字列オブジェクトに変換されて例外の "
付属値" に保存されます。

もう一つ有用な関数として "PyErr_SetFromErrno()" があります。この関数は
引数に例外だけをとり、付属値はグローバル変数 "errno" から構築します。
もっとも汎用的な関数は "PyErr_SetObject()" で、二つのオブジェクト、例
外と付属値を引数にとります。これら関数に渡すオブジェクトには
"Py_INCREF()" を使う必要はありません。

例外がセットされているかどうかは、 "PyErr_Occurred()" を使って非破壊的
に調べられます。この関数は現在の例外オブジェクトを返します。例外が発生
していない場合には "NULL" を返します。通常は、関数の戻り値からエラーが
発生したかを判別できるはずなので、 "PyErr_Occurred()" を呼び出す必要は
ありません。

関数 *g* を呼び出す *f* が、前者の関数の呼び出しに失敗したことを検出す
ると、 *f* 自体はエラー値 (大抵は "NULL" や "-1") を返さねばなりません
。しかし、 "PyErr_*" 関数群のいずれかを呼び出す必要は *ありません* ---
なぜなら、 *g* がすでに呼び出しているからです。次いで *f* を呼び出した
コードもエラーを示す値を *自らを呼び出したコード* に返すことになります
が、同様に "PyErr_*" は *呼び出しません* 。以下同様に続きます --- エラ
ーの最も詳しい原因は、最初にエラーを検出した関数がすでに報告しているか
らです。エラーが Python インタプリタのメインループに到達すると、現在実
行中の Python コードは一時停止し、 Python プログラマが指定した例外ハン
ドラを探し出そうとします。

(モジュールが "PyErr_*" 関数をもう一度呼び出して、より詳細なエラーメッ
セージを提供するような状況があります。このような状況ではそうすべきです
。とはいえ、一般的な規則としては、この関数を何度も呼び出す必要はなく、
ともすればエラーの原因に関する情報を失う結果になりがちです: これにより
、ほとんどの操作が様々な理由から失敗するかもしれません)

ある関数呼び出しでの処理の失敗によってセットされた例外を無視するには、
"PyErr_Clear()" を呼び出して例外状態を明示的に消去しなくてはなりません
。エラーをインタプリタには渡したくなく、自前で (何か他の作業を行ったり
、何も起こらなかったかのように見せかけるような) エラー処理を完全に行う
場合にのみ、 "PyErr_Clear()" を呼び出すようにすべきです。

"malloc()" の呼び出し失敗は、常に例外にしなくてはなりません ---
"malloc()" (または "realloc()") を直接呼び出しているコードは、
"PyErr_NoMemory()" を呼び出して、失敗を示す値を返さねばなりません。オ
ブジェクトを生成する全ての関数 (例えば "PyLong_FromLong()") は
"PyErr_NoMemory()" の呼び出しを済ませてしまうので、この規則が関係する
のは直接 "malloc()" を呼び出すコードだけです。

また、 "PyArg_ParseTuple()" という重要な例外を除いて、整数の状態コード
を返す関数はたいてい、Unix のシステムコールと同じく、処理が成功した際
にはゼロまたは正の値を返し、失敗した場合には "-1" を返します。

最後に、エラー標示値を返す際に、(エラーが発生するまでに既に生成してし
まったオブジェクトに対して "Py_XDECREF()" や "Py_DECREF()" を呼び出し
て) ごみ処理を注意深く行ってください!

The choice of which exception to raise is entirely yours.  There are
predeclared C objects corresponding to all built-in Python exceptions,
such as "PyExc_ZeroDivisionError", which you can use directly. Of
course, you should choose exceptions wisely --- don't use
"PyExc_TypeError" to mean that a file couldn't be opened (that should
probably be "PyExc_OSError"). If something's wrong with the argument
list, the "PyArg_ParseTuple()" function usually raises
"PyExc_TypeError".  If you have an argument whose value must be in a
particular range or must satisfy other conditions, "PyExc_ValueError"
is appropriate.

モジュール固有の新たな例外も定義できます。定義するには、通常はファイル
の先頭部分に静的なオブジェクト変数の宣言を行います:

   static PyObject *SpamError;

and initialize it in your module's initialization function
("PyInit_spam()") with an exception object:

   PyMODINIT_FUNC
   PyInit_spam(void)
   {
       PyObject *m;

       m = PyModule_Create(&spammodule);
       if (m == NULL)
           return NULL;

       SpamError = PyErr_NewException("spam.error", NULL, NULL);
       if (PyModule_AddObjectRef(m, "error", SpamError) < 0) {
           Py_CLEAR(SpamError);
           Py_DECREF(m);
           return NULL;
       }

       return m;
   }

Note that the Python name for the exception object is "spam.error".
The "PyErr_NewException()" function may create a class with the base
class being "Exception" (unless another class is passed in instead of
"NULL"), described in 組み込み例外.

Note also that the "SpamError" variable retains a reference to the
newly created exception class; this is intentional!  Since the
exception could be removed from the module by external code, an owned
reference to the class is needed to ensure that it will not be
discarded, causing "SpamError" to become a dangling pointer. Should it
become a dangling pointer, C code which raises the exception could
cause a core dump or other unintended side effects.

We discuss the use of "PyMODINIT_FUNC" as a function return type later
in this sample.

The "spam.error" exception can be raised in your extension module
using a call to "PyErr_SetString()" as shown below:

   static PyObject *
   spam_system(PyObject *self, PyObject *args)
   {
       const char *command;
       int sts;

       if (!PyArg_ParseTuple(args, "s", &command))
           return NULL;
       sts = system(command);
       if (sts < 0) {
           PyErr_SetString(SpamError, "System command failed");
           return NULL;
       }
       return PyLong_FromLong(sts);
   }


1.3. 例に戻る
=============

先ほどの関数の例に戻ると、今度は以下の実行文を理解できるはずです:

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

It returns "NULL" (the error indicator for functions returning object
pointers) if an error is detected in the argument list, relying on the
exception set by "PyArg_ParseTuple()".  Otherwise the string value of
the argument has been copied to the local variable "command".  This is
a pointer assignment and you are not supposed to modify the string to
which it points (so in Standard C, the variable "command" should
properly be declared as "const char *command").

次の文では、 "PyArg_ParseTuple()" で得た文字列を渡して Unix 関数
"system()" を呼び出しています:

   sts = system(command);

Our "spam.system()" function must return the value of "sts" as a
Python object.  This is done using the function "PyLong_FromLong()".

   return PyLong_FromLong(sts);

上の場合では、整数オブジェクトを返します。(そう、整数ですら、 Python
においてはヒープ上のオブジェクトなのです! )

何ら有用な値を返さない関数 (void を返す関数) に対応する Python の関数
は "None" を返さねばなりません。関数に "None" を返させるには、以下のよ
うな慣用句を使います (この慣用句は "Py_RETURN_NONE" マクロに実装されて
います):

   Py_INCREF(Py_None);
   return Py_None;

"Py_None" は特殊な Pyhton オブジェクトである "None" に対応する C での
名前です。これまで見てきたようにほとんどのコンテキストで "エラー" を意
味する "NULL" ポインタとは違い、 "None" は純粋な Python のオブジェクト
です。


1.4. モジュールのメソッドテーブルと初期化関数
=============================================

I promised to show how "spam_system()" is called from Python programs.
First, we need to list its name and address in a "method table":

   static PyMethodDef SpamMethods[] = {
       ...
       {"system",  spam_system, METH_VARARGS,
        "Execute a shell command."},
       ...
       {NULL, NULL, 0, NULL}        /* Sentinel */
   };

リスト要素の三つ目のエントリ ("METH_VARARGS") に注意してください。この
エントリは、C 関数が使う呼び出し規約をインタプリタに教えるためのフラグ
です。通常この値は "METH_VARARGS" か "METH_VARARGS | METH_KEYWORDS" の
はずです; "0" は旧式の "PyArg_ParseTuple()" の変化形が使われることを意
味します。

"METH_VARARGS" だけを使う場合、C 関数は、Python レベルでの引数が
"PyArg_ParseTuple()" が受理できるタプルの形式で渡されるものと想定しな
ければなりません; この関数についての詳細は下で説明します。

The "METH_KEYWORDS" bit may be set in the third field if keyword
arguments should be passed to the function.  In this case, the C
function should accept a third "PyObject *" parameter which will be a
dictionary of keywords. Use "PyArg_ParseTupleAndKeywords()" to parse
the arguments to such a function.

メソッドテーブルはモジュール定義の構造体から参照されていなければなりま
せん:

   static struct PyModuleDef spammodule = {
       PyModuleDef_HEAD_INIT,
       "spam",   /* name of module */
       spam_doc, /* module documentation, may be NULL */
       -1,       /* size of per-interpreter state of the module,
                    or -1 if the module keeps state in global variables. */
       SpamMethods
   };

This structure, in turn, must be passed to the interpreter in the
module's initialization function.  The initialization function must be
named "PyInit_name()", where *name* is the name of the module, and
should be the only non-"static" item defined in the module file:

   PyMODINIT_FUNC
   PyInit_spam(void)
   {
       return PyModule_Create(&spammodule);
   }

Note that "PyMODINIT_FUNC" declares the function as "PyObject *"
return type, declares any special linkage declarations required by the
platform, and for C++ declares the function as "extern "C"".

When the Python program imports module "spam" for the first time,
"PyInit_spam()" is called. (See below for comments about embedding
Python.) It calls "PyModule_Create()", which returns a module object,
and inserts built-in function objects into the newly created module
based upon the table (an array of "PyMethodDef" structures) found in
the module definition. "PyModule_Create()" returns a pointer to the
module object that it creates.  It may abort with a fatal error for
certain errors, or return "NULL" if the module could not be
initialized satisfactorily. The init function must return the module
object to its caller, so that it then gets inserted into
"sys.modules".

When embedding Python, the "PyInit_spam()" function is not called
automatically unless there's an entry in the "PyImport_Inittab" table.
To add the module to the initialization table, use
"PyImport_AppendInittab()", optionally followed by an import of the
module:

   #define PY_SSIZE_T_CLEAN
   #include <Python.h>

   int
   main(int argc, char *argv[])
   {
       PyStatus status;
       PyConfig config;
       PyConfig_InitPythonConfig(&config);

       /* Add a built-in module, before Py_Initialize */
       if (PyImport_AppendInittab("spam", PyInit_spam) == -1) {
           fprintf(stderr, "Error: could not extend in-built modules table\n");
           exit(1);
       }

       /* Pass argv[0] to the Python interpreter */
       status = PyConfig_SetBytesString(&config, &config.program_name, argv[0]);
       if (PyStatus_Exception(status)) {
           goto exception;
       }

       /* Initialize the Python interpreter.  Required.
          If this step fails, it will be a fatal error. */
       status = Py_InitializeFromConfig(&config);
       if (PyStatus_Exception(status)) {
           goto exception;
       }
       PyConfig_Clear(&config);

       /* Optionally import the module; alternatively,
          import can be deferred until the embedded script
          imports it. */
       PyObject *pmodule = PyImport_ImportModule("spam");
       if (!pmodule) {
           PyErr_Print();
           fprintf(stderr, "Error: could not import module 'spam'\n");
       }

       // ... use Python C API here ...

       return 0;

     exception:
        PyConfig_Clear(&config);
        Py_ExitStatusException(status);
   }

注釈:

  単一のプロセス内 (または "fork()" 後の "exec()" が介入していない状態
  ) における複数のインタプリタにおいて、 "sys.modules" からエントリを
  除去したり新たなコンパイル済みモジュールを import したりすると、拡張
  モジュールによっては問題を生じることがあります。拡張モジュールの作者
  は、内部データ構造を初期化する際にはよくよく用心すべきです。

より実質的なモジュール例は、Python ソース配布物に "Modules/xxmodule.c"
という名前で入っています。このファイルはテンプレートとしても利用できま
すし、単に例としても読めます。

注釈:

  "xmodule" は "spam" と異なり、 *多段階初期化 (multi-phase
  initialization* (Python 3.5 の新機能) を使っています。 "PyInit_spam"
  が PyModuleDef を返し、モジュールの生成は後に import 機構が行います
  。多段階初期化についての詳細は **PEP 489** を参照してください。


1.5. コンパイルとリンク
=======================

新しい拡張モジュールを使えるようになるまで、まだ二つの作業: コンパイル
と、Python システムへのリンク、が残っています。動的読み込み (dynamic
loading) を使っているのなら、作業の詳細は自分のシステムが使っている動
的読み込みの形式によって変わるかもしれません; 詳しくは、拡張モジュール
のビルドに関する章 (C および C++ 拡張のビルド 章) や、Windows における
ビルドに関係する追加情報の章 (Windows 上での C および C++ 拡張モジュー
ルのビルド 章) を参照してください。

動的読み込みを使えなかったり、モジュールを常時 Python インタプリタの一
部にしておきたい場合には、インタプリタのビルド設定を変更して再ビルドし
なければならなくなるでしょう。Unixでは、幸運なことにこの作業はとても単
純です: 単に自作のモジュールファイル (例えば "spammodule.c") を展開し
たソース配布物の "Modules/"  ディレクトリに置き、
"Modules/Setup.local" に自分のファイルを説明する以下の一行:

   spam spammodule.o

を追加して、トップレベルのディレクトリで **make** を実行して、インタプ
リタを再ビルドするだけです。 "Modules/" サブディレクトリでも **make**
を実行できますが、前もって '**make** Makefile' を実行して "Makefile"
を再ビルドしておかなければならりません。(この作業は "Setup" ファイルを
変更するたびに必要です。)

モジュールが別のライブラリとリンクされている必要がある場合、ライブラリ
も設定ファイルに列挙できます。例えば以下のようにします。

   spam spammodule.o -lX11


1.6. C から Python 関数を呼び出す
=================================

これまでは、Python からの C 関数の呼び出しに重点を置いて述べてきました
。ところでこの逆: C からの Python 関数の呼び出しもまた有用です。とりわ
け、いわゆる "コールバック" 関数をサポートするようなライブラリを作成す
る際にはこの機能が便利です。ある C インターフェースがコールバックを利
用している場合、同等の機能を提供する Python コードでは、しばしば
Python プログラマにコールバック機構を提供する必要があります; このとき
実装では、 C で書かれたコールバック関数から Python で書かれたコールパ
ック関数を呼び出すようにする必要があるでしょう。もちろん、他の用途も考
えられます。

幸運なことに、Python インタプリタは簡単に再帰呼び出しでき、 Python 関
数を呼び出すための標準インターフェースもあります。 (Python パーザを特
定の入力文字を使って呼び出す方法について詳説するつもりはありません ---
この方法に興味があるなら、 Python ソースコードの "Modules/main.c" にあ
る、コマンドラインオプション "-c" の実装を見てください)

Python 関数の呼び出しは簡単です。まず、C のコードに対してコールバック
を登録しようとする Python プログラムは、何らかの方法で Python の関数オ
ブジェクトを渡さねばなりません。このために、コールバック登録関数 (また
はその他のインターフェース) を提供せねばなりません。このコールバック登
録関数が呼び出された際に、引き渡された Python 関数オブジェクトへのポイ
ンタをグローバル変数に --- あるいは、どこか適切な場所に --- 保存します
(関数オブジェクトを "Py_INCREF()" するようよく注意してください!)。例え
ば、以下のような関数がモジュールの一部になっていることでしょう:

   static PyObject *my_callback = NULL;

   static PyObject *
   my_set_callback(PyObject *dummy, PyObject *args)
   {
       PyObject *result = NULL;
       PyObject *temp;

       if (PyArg_ParseTuple(args, "O:set_callback", &temp)) {
           if (!PyCallable_Check(temp)) {
               PyErr_SetString(PyExc_TypeError, "parameter must be callable");
               return NULL;
           }
           Py_XINCREF(temp);         /* Add a reference to new callback */
           Py_XDECREF(my_callback);  /* Dispose of previous callback */
           my_callback = temp;       /* Remember new callback */
           /* Boilerplate to return "None" */
           Py_INCREF(Py_None);
           result = Py_None;
       }
       return result;
   }

This function must be registered with the interpreter using the
"METH_VARARGS" flag; this is described in section モジュールのメソッド
テーブルと初期化関数.  The "PyArg_ParseTuple()" function and its
arguments are documented in section 拡張モジュール関数でのパラメタ展開
.

"Py_XINCREF()" および "Py_XDECREF()" は、オブジェクトに対する参照カウ
ントをインクリメント/デクリメントするためのマクロで、 "NULL" ポインタ
が渡されても安全に操作できる形式です (とはいえ、上の流れでは *temp* が
"NULL" になることはありません)。これらのマクロと参照カウントについては
、 参照カウント法 で説明しています。

その後、コールバック関数を呼び出す時が来たら、C 関数
"PyObject_CallObject()" を呼び出します。この関数には二つの引数: Python
関数と Python 関数の引数リストがあり、いずれも任意の Python オブジェク
トを表すポインタ型です。引数リストは常にタプルオブジェクトでなければな
らず、その長さは引数の数になります。Python 関数を引数なしで呼び出すの
なら、 "NULL" か空のタプルを渡します; 単一の引数で関数を呼び出すのなら
、単要素 (singleton) のタプルを渡します。 "Py_BuildValue()" の書式文字
列中に、ゼロ個または一個以上の書式化コードが入った丸括弧がある場合、こ
の関数はタプルを返します。以下に例を示します:

   int arg;
   PyObject *arglist;
   PyObject *result;
   ...
   arg = 123;
   ...
   /* Time to call the callback */
   arglist = Py_BuildValue("(i)", arg);
   result = PyObject_CallObject(my_callback, arglist);
   Py_DECREF(arglist);

"PyObject_CallObject()" は Python オブジェクトへのポインタを返します:
これは Python 関数からの戻り値になります。 "PyObject_CallObject()" は
、引数に対して "参照カウント中立 (reference-count- neutral)" です。上
の例ではタプルを生成して引数リストとして提供しており、このタプルは
"PyObject_CallObject()" の呼び出し直後に "Py_DECREF()" されています。

"PyObject_CallObject()" は戻り値として "新しい" オブジェクト: 新規に作
成されたオブジェクトか、既存のオブジェクトの参照カウントをインクリメン
トしたものを返します。従って、このオブジェクトをグローバル変数に保存し
たいのでないかぎり、たとえこの戻り値に興味がなくても (むしろ、そうであ
ればなおさら!) 何がしかの方法で戻り値オブジェクトを "Py_DECREF()" しな
ければなりません。

とはいえ、戻り値を "Py_DECREF()" する前には、値が "NULL" でないかチェ
ックしておくことが重要です。もし "NULL" なら、呼び出した Python 関数は
例外を送出して終了させられています。 "PyObject_CallObject()" を呼び出
しているコード自体もまた Python から呼び出されているのであれば、今度は
C コードが自分を呼び出している Python コードにエラー標示値を返さねばな
りません。それにより、インタプリタはスタックトレースを出力したり、例外
を処理するための Python コードを呼び出したりできます。例外の送出が不可
能だったり、したくないのなら、 "PyErr_Clear()" を呼んで例外を消去して
おかねばなりません。例えば以下のようにします:

   if (result == NULL)
       return NULL; /* Pass error back */
   ...use result...
   Py_DECREF(result);

Python コールバック関数をどんなインターフェースにしたいかによっては、
引数リストを "PyObject_CallObject()" に与えなければならない場合もあり
ます。あるケースでは、コールバック関数を指定したのと同じインターフェー
スを介して、引数リストも渡されているかもしれません。また別のケースでは
、新しいタプルを構築して引数リストを渡さねばならないかもしれません。こ
の場合最も簡単なのは "Py_BuildValue()" を呼ぶやり方です。例えば、整数
のイベントコードを渡したければ、以下のようなコードを使うことになるでし
ょう:

   PyObject *arglist;
   ...
   arglist = Py_BuildValue("(l)", eventcode);
   result = PyObject_CallObject(my_callback, arglist);
   Py_DECREF(arglist);
   if (result == NULL)
       return NULL; /* Pass error back */
   /* Here maybe use the result */
   Py_DECREF(result);

"Py_DECREF(arglist)" が呼び出しの直後、エラーチェックよりも前に置かれ
ていることに注意してください! また、厳密に言えば、このコードは完全では
ありません: "Py_BuildValue()" はメモリ不足におちいるかもしれず、チェッ
クしておくべきです。

通常の引数とキーワード引数をサポートする "PyObject_Call()" を使って、
キーワード引数を伴う関数呼び出しをすることができます。上の例と同じよう
に、 "Py_BuildValue()" を作って辞書を作ります。

   PyObject *dict;
   ...
   dict = Py_BuildValue("{s:i}", "name", val);
   result = PyObject_Call(my_callback, NULL, dict);
   Py_DECREF(dict);
   if (result == NULL)
       return NULL; /* Pass error back */
   /* Here maybe use the result */
   Py_DECREF(result);


1.7. 拡張モジュール関数でのパラメタ展開
=======================================

"PyArg_ParseTuple()" 関数は以下のように宣言されています:

   int PyArg_ParseTuple(PyObject *arg, const char *format, ...);

引数 *arg* は C 関数から Python に渡される引数リストが入ったタプルオブ
ジェクトでなければなりません。 *format* 引数は書式文字列で、 Python/C
API リファレンスマニュアルの 引数の解釈と値の構築 で解説されている書法
に従わねばなりません。残りの引数は、それぞれの変数のアドレスで、書式化
文字列から決まる型になっていなければなりません。

"PyArg_ParseTuple()" は Python 側から与えられた引数が必要な型になって
いるか調べるのに対し、 "PyArg_ParseTuple()" は呼び出しの際に渡された C
変数のアドレスが有効な値を持つか調べられないことに注意してください: こ
こで間違いを犯すと、コードがクラッシュするかもしれませんし、少なくとも
でたらめなビットをメモリに上書きしてしまいます。慎重に!

呼び出し側に提供されるオブジェクトへの参照はすべて *借用* 参照
(borrowed reference) になります; これらのオブジェクトの参照カウントを
デクリメントしてはなりません!

以下にいくつかの呼び出し例を示します:

   #define PY_SSIZE_T_CLEAN
   #include <Python.h>

   int ok;
   int i, j;
   long k, l;
   const char *s;
   Py_ssize_t size;

   ok = PyArg_ParseTuple(args, ""); /* No arguments */
       /* Python call: f() */

   ok = PyArg_ParseTuple(args, "s", &s); /* A string */
       /* Possible Python call: f('whoops!') */

   ok = PyArg_ParseTuple(args, "lls", &k, &l, &s); /* Two longs and a string */
       /* Possible Python call: f(1, 2, 'three') */

   ok = PyArg_ParseTuple(args, "(ii)s#", &i, &j, &s, &size);
       /* A pair of ints and a string, whose size is also returned */
       /* Possible Python call: f((1, 2), 'three') */

   {
       const char *file;
       const char *mode = "r";
       int bufsize = 0;
       ok = PyArg_ParseTuple(args, "s|si", &file, &mode, &bufsize);
       /* A string, and optionally another string and an integer */
       /* Possible Python calls:
          f('spam')
          f('spam', 'w')
          f('spam', 'wb', 100000) */
   }

   {
       int left, top, right, bottom, h, v;
       ok = PyArg_ParseTuple(args, "((ii)(ii))(ii)",
                &left, &top, &right, &bottom, &h, &v);
       /* A rectangle and a point */
       /* Possible Python call:
          f(((0, 0), (400, 300)), (10, 10)) */
   }

   {
       Py_complex c;
       ok = PyArg_ParseTuple(args, "D:myfunction", &c);
       /* a complex, also providing a function name for errors */
       /* Possible Python call: myfunction(1+2j) */
   }


1.8. 拡張モジュール関数のキーワードパラメタ
===========================================

"PyArg_ParseTupleAndKeywords()" は、以下のように宣言されています:

   int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,
                                   const char *format, char * const *kwlist, ...);

*arg* と *format* パラメタは "PyArg_ParseTuple()" のものと同じです。
*kwdict* パラメタはキーワード引数の入った辞書で、 Python ランタイムシ
ステムから第三パラメタとして受け取ります。 *kwlist* パラメタは各パラメ
タを識別するための文字列からなる、 "NULL" 終端されたリストです; 各パラ
メタ名は *format* 中の型情報に対して左から右の順に照合されます。成功す
ると "PyArg_ParseTupleAndKeywords()" は真を返し、それ以外の場合には適
切な例外を送出して偽を返します。

注釈:

  キーワード引数を使っている場合、タプルは入れ子にして使えません!
  *kwlist* 内に存在しないキーワードパラメタが渡された場合、
  "TypeError" の送出を引き起こします。

以下にキーワードを使ったモジュール例を示します。これは Geoff Philbrick
(philbrick@hks.com) によるプログラム例をもとにしています:

   #define PY_SSIZE_T_CLEAN
   #include <Python.h>

   static PyObject *
   keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)
   {
       int voltage;
       const char *state = "a stiff";
       const char *action = "voom";
       const char *type = "Norwegian Blue";

       static char *kwlist[] = {"voltage", "state", "action", "type", NULL};

       if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist,
                                        &voltage, &state, &action, &type))
           return NULL;

       printf("-- This parrot wouldn't %s if you put %i Volts through it.\n",
              action, voltage);
       printf("-- Lovely plumage, the %s -- It's %s!\n", type, state);

       Py_RETURN_NONE;
   }

   static PyMethodDef keywdarg_methods[] = {
       /* The cast of the function is necessary since PyCFunction values
        * only take two PyObject* parameters, and keywdarg_parrot() takes
        * three.
        */
       {"parrot", (PyCFunction)(void(*)(void))keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
        "Print a lovely skit to standard output."},
       {NULL, NULL, 0, NULL}   /* sentinel */
   };

   static struct PyModuleDef keywdargmodule = {
       PyModuleDef_HEAD_INIT,
       "keywdarg",
       NULL,
       -1,
       keywdarg_methods
   };

   PyMODINIT_FUNC
   PyInit_keywdarg(void)
   {
       return PyModule_Create(&keywdargmodule);
   }


1.9. 任意の値を構築する
=======================

"Py_BuildValue()" は "PyArg_ParseTuple()" の対極に位置するものです。こ
の関数は以下のように定義されています:

   PyObject *Py_BuildValue(const char *format, ...);

"Py_BuildValue()" は、 "PyArg_ParseTuple()" の認識する一連の書式単位に
似た書式単位を認識します。ただし (関数への出力ではなく、入力に使われる
) 引数はポインタではなく、ただの値でなければなりません。 Python から呼
び出された C 関数が返す値として適切な、新たな Python オブジェクトを返
します。

"PyArg_ParseTuple()" とは一つ違う点があります: "PyArg_ParseTuple()" は
第一引数をタプルにする必要があります (Python の引数リストは内部的には
常にタプルとして表現されるからです) が、 "Py_BuildValue()" はタプルを
生成するとは限りません。 "Py_BuildValue()" は書式文字列中に書式単位が
二つかそれ以上入っている場合にのみタプルを構築します。書式文字列が空な
ら、 "None" を返します。きっかり一つの書式単位なら、その書式単位が記述
している何らかのオブジェクトになります。サイズが 0 や 1 のタプル返させ
たいのなら、書式文字列を丸括弧で囲います。

以下に例を示します (左に呼び出し例を、右に構築される Python 値を示しま
す):

   Py_BuildValue("")                        None
   Py_BuildValue("i", 123)                  123
   Py_BuildValue("iii", 123, 456, 789)      (123, 456, 789)
   Py_BuildValue("s", "hello")              'hello'
   Py_BuildValue("y", "hello")              b'hello'
   Py_BuildValue("ss", "hello", "world")    ('hello', 'world')
   Py_BuildValue("s#", "hello", 4)          'hell'
   Py_BuildValue("y#", "hello", 4)          b'hell'
   Py_BuildValue("()")                      ()
   Py_BuildValue("(i)", 123)                (123,)
   Py_BuildValue("(ii)", 123, 456)          (123, 456)
   Py_BuildValue("(i,i)", 123, 456)         (123, 456)
   Py_BuildValue("[i,i]", 123, 456)         [123, 456]
   Py_BuildValue("{s:i,s:i}",
                 "abc", 123, "def", 456)    {'abc': 123, 'def': 456}
   Py_BuildValue("((ii)(ii)) (ii)",
                 1, 2, 3, 4, 5, 6)          (((1, 2), (3, 4)), (5, 6))


1.10. 参照カウント法
====================

C や C++のような言語では、プログラマはヒープ上のメモリを動的に確保した
り解放したりする責任があります。こうした作業は C では関数 "malloc()"
や "free()" で行います。C++では本質的に同じ意味で演算子 "new" や
"delete" が使われます。そこで、以下の議論は C の場合に限定して行います
。

Every block of memory allocated with "malloc()" should eventually be
returned to the pool of available memory by exactly one call to
"free()". It is important to call "free()" at the right time.  If a
block's address is forgotten but "free()" is not called for it, the
memory it occupies cannot be reused until the program terminates.
This is called a *memory leak*.  On the other hand, if a program calls
"free()" for a block and then continues to use the block, it creates a
conflict with reuse of the block through another "malloc()" call.
This is called *using freed memory*. It has the same bad consequences
as referencing uninitialized data --- core dumps, wrong results,
mysterious crashes.

よくあるメモリリークの原因はコード中の普通でない処理経路です。例えば、
ある関数があるメモリブロックを確保し、何らかの計算を行って、再度ブロッ
クを解放するとします。さて、関数の要求仕様を変更して、計算に対するテス
トを追加すると、エラー条件を検出し、関数の途中で処理を戻すようになるか
もしれません。この途中での終了が起きるとき、確保されたメモリブロックは
解放し忘れやすいのです。コードが後で追加された場合には特にそうです。こ
のようなメモリリークが一旦紛れ込んでしまうと、長い間検出されないままに
なることがよくあります: エラーによる関数の終了は、全ての関数呼び出しの
に対してほんのわずかな割合しか起きず、その一方でほとんどの近代的な計算
機は相当量の仮想記憶を持っているため、メモリリークが明らかになるのは、
長い間動作していたプロセスがリークを起こす関数を何度も使った場合に限ら
れるからです。従って、この種のエラーを最小限にとどめるようなコーディン
グ規約や戦略を設けて、不慮のメモリリークを避けることが重要なのです。

Python は "malloc()" や "free()" を非常によく利用するため、メモリリー
クの防止に加え、解放されたメモリの使用を防止する戦略が必要です。このた
めに選ばれたのが参照カウント法 (*reference counting*) と呼ばれる手法で
す。参照カウント法の原理は簡単です: 全てのオブジェクトにはカウンタがあ
り、オブジェクトに対する参照がどこかに保存されたらカウンタをインクリメ
ントし、オブジェクトに対する参照が削除されたらデクリメントします。カウ
ンタがゼロになったら、オブジェクトへの最後の参照が削除されたことになり
、オブジェクトは解放されます。

もう一つの戦略は自動ガベージコレクション (*automatic garbage
collection*) と呼ばれています。 (参照カウント法はガベージコレクション
戦略の一つとして挙げられることもあるので、二つを区別するために筆者は "
自動 (automatic)" を使っています。) 自動ガベージコレクションの大きな利
点は、ユーザが "free()" を明示的によばなくてよいことにあります。 (速度
やメモリの有効利用性も利点として主張されています --- が、これは確たる
事実ではありません。) C における自動ガベージコレクションの欠点は、真に
可搬性のあるガベージコレクタが存在しないということです。それに対し、参
照カウント法は可搬性のある実装ができます ("malloc()" や "free()" を利
用できるのが前提です --- C 標準はこれを保証しています)。いつの日か、十
分可搬性のあるガベージコレクタが C で使えるようになるかもしれませんが
、それまでは参照カウント法でやっていく以外にはないのです。

Python では、伝統的な参照カウント法の実装を行っている一方で、参照の循
環を検出するために働く循環参照検出機構 (cycle detector) も提供していま
す。循環参照検出機構のおかげで、直接、間接にかかわらず循環参照の生成を
気にせずにアプリケーションを構築できます; というのも、参照カウント法だ
けを使ったガベージコレクション実装にとって循環参照は弱点だからです。循
環参照は、(間接参照の場合も含めて) 相互への参照が入ったオブジェクトか
ら形成されるため、循環内のオブジェクトは各々非ゼロの参照カウントを持ち
ます。典型的な参照カウント法の実装では、たとえ循環参照を形成するオブジ
ェクトに対して他に全く参照がないとしても、循環参照内のどのオブジェクト
に属するメモリも再利用できません。

循環参照検出機構はそのようなガベージサイクル (前述したような循環参照オ
ブジェクト) を検出して回収することができます。 "gc" モジュールそのよう
な検出機構の実行 ("collect()" 関数) を提供するとともに、設定のためのイ
ンタフェースおよび検出機構を実行時に無効にする方法も提供しています。


1.10.1. Python における参照カウント法
-------------------------------------

Python には、参照カウントのインクリメントやデクリメントを処理する二つ
のマクロ、 "Py_INCREF(x)" と "Py_DECREF(x)" があります。 "Py_DECREF()"
は、参照カウントがゼロに到達した際に、オブジェクトのメモリ解放も行いま
す。柔軟性を持たせるために、 "free()" を直接呼び出しません --- その代
わりにオブジェクトの型オブジェクト (*type object*) を介します。このた
めに (他の目的もありますが)、全てのオブジェクトには自身の型オブジェク
トに対するポインタが入っています。

さて、まだ重大な疑問が残っています: いつ "Py_INCREF(x)" や
"Py_DECREF(x)" を使えばよいのでしょうか? まず、いくつかの用語説明から
始めさせてください。まず、オブジェクトは "占有 (own)" されることはあり
ません; しかし、あるオブジェクトに対する参照の所有 *own a reference*
はできます。オブジェクトの参照カウントは、そのオブジェクトが参照の所有
を受けている回数と定義されています。参照の所有者は、参照が必要なくなっ
た際に "Py_DECREF()" を呼び出す役割を担います。参照の所有権は委譲
(transfer) できます。所有参照 (owned reference) の放棄には、渡す、保存
する、 "Py_DECREF()" を呼び出す、という三つの方法があります。所有参照
を処理し忘れると、メモリリークを引き起こします。

オブジェクトに対する参照は、借用 (*borrow*) も可能です。 [2] 参照の借
用者は、 "Py_DECREF()" を呼んではなりません。借用者は、参照の所有者か
ら借用した期間を超えて参照を保持し続けてはなりません。所有者が参照を放
棄した後で借用参照を使うと、解放済みメモリを使用してしまう危険があるの
で、絶対に避けねばなりません。 [3]

参照の借用が参照の所有よりも優れている点は、コードがとりうるあらゆる処
理経路で参照を廃棄しておくよう注意しなくて済むことです --- 別の言い方
をすれば、借用参照の場合には、処理の途中で関数を終了してもメモリリーク
の危険を冒すことがない、ということです。逆に、所有よりも不利な点は、ご
くまともに見えるコードが、実際には参照の借用元で放棄されてしまった後に
その参照を使うかもしれないような微妙な状況があるということです。

"Py_INCREF()" を呼び出すと、借用参照を所有参照に変更できます。この操作
は参照の借用元の状態には影響しません --- "Py_INCREF()" は新たな所有参
照を生成し、参照の所有者が担うべき全ての責任を課します (つまり、新たな
参照の所有者は、以前の所有者と同様、参照の放棄を適切に行わねばなりませ
ん)。


1.10.2. 所有権にまつわる規則
----------------------------

オブジェクトへの参照を関数の内外に渡す場合には、オブジェクトの所有権が
参照と共に渡されるか否かが常に関数インターフェース仕様の一部となります
。

オブジェクトへの参照を返すほとんどの関数は、参照とともに所有権も渡しま
す。特に、 "PyLong_FromLong()" や "Py_BuildValue()" のように、新しいオ
ブジェクトを生成する関数は全て所有権を相手に渡します。オブジェクトが実
際には新たなオブジェクトでなくても、そのオブジェクトに対する新たな参照
の所有権を得ます。例えば、 "PyLong_FromLong()" はよく使う値をキャッシ
ュしており、キャッシュされた値への参照を返すことがあります。

"PyObject_GetAttrString()" のように、あるオブジェクトから別のオブジェ
クトを抽出するような関数もまた、参照とともに所有権を委譲します。こちら
の方はやや理解しにくいかもしれません。というのはよく使われるルーチンの
いくつかが例外となっているからです: "PyTuple_GetItem()" 、
"PyList_GetItem()" 、 "PyDict_GetItem()" 、および
"PyDict_GetItemString()" は全て、タプル、リスト、または辞書から借用参
照を返します。

"PyImport_AddModule()" は、実際にはオブジェクトを生成して返すことがあ
るにもかかわらず、借用参照を返します: これが可能なのは、生成されたオブ
ジェクトに対する所有参照は "sys.modules" に保持されるからです。

オブジェクトへの参照を別の関数に渡す場合、一般的には、関数側は呼び出し
手から参照を借用します --- 参照を保存する必要があるなら、関数側は
"Py_INCREF()" を呼び出して独立した所有者になります。とはいえ、この規則
には二つの重要な例外: "PyTuple_SetItem()" と "PyList_SetItem()" があり
ます。これらの関数は、渡された引数要素に対して所有権を乗っ取り (take
over) ます --- たとえ失敗してもです! ("PyDict_SetItem()" とその仲間は
所有権を乗っ取りません --- これらはいわば "普通の" 関数です。)

Python から C 関数が呼び出される際には、C 関数は呼び出し側から引数への
参照を借用します。C 関数の呼び出し側はオブジェクトへの参照を所有してい
るので、借用参照の生存期間が保証されるのは関数が処理を返すまでです。こ
のようにして借用参照を保存したり他に渡したりしたい場合にのみ、
"Py_INCREF()" を使って所有参照にする必要があります。

Python から呼び出された C 関数が返す参照は所有参照でなければなりません
--- 所有権は関数から呼び出し側へと委譲されます。


1.10.3. 薄氷
------------

数少ない状況において、一見無害に見える借用参照の利用が問題をひきおこす
ことがあります。この問題はすべて、インタプリタが非明示的に呼び出され、
インタプリタが参照の所有者に参照を放棄させてしまう状況と関係しています
。

知っておくべきケースのうち最初の、そして最も重要なものは、リスト要素に
対する参照を借りている際に起きる、関係ないオブジェクトに対する
"Py_DECREF()" の使用です。例えば:

   void
   bug(PyObject *list)
   {
       PyObject *item = PyList_GetItem(list, 0);

       PyList_SetItem(list, 1, PyLong_FromLong(0L));
       PyObject_Print(item, stdout, 0); /* BUG! */
   }

上の関数はまず、 "list[0]" への参照を借用し、次に "list[1]" を値 "0"
で置き換え、最後にさきほど借用した参照を出力しています。何も問題ないよ
うに見えますね? でもそうではないのです!

Let's follow the control flow into "PyList_SetItem()".  The list owns
references to all its items, so when item 1 is replaced, it has to
dispose of the original item 1.  Now let's suppose the original item 1
was an instance of a user-defined class, and let's further suppose
that the class defined a "__del__()" method.  If this class instance
has a reference count of 1, disposing of it will call its "__del__()"
method.

Since it is written in Python, the "__del__()" method can execute
arbitrary Python code.  Could it perhaps do something to invalidate
the reference to "item" in "bug()"?  You bet!  Assuming that the list
passed into "bug()" is accessible to the "__del__()" method, it could
execute a statement to the effect of "del list[0]", and assuming this
was the last reference to that object, it would free the memory
associated with it, thereby invalidating "item".

問題の原因が分かれば、解決は簡単です。一時的に参照回数を増やせばよいの
です。正しく動作するバージョンは以下のようになります:

   void
   no_bug(PyObject *list)
   {
       PyObject *item = PyList_GetItem(list, 0);

       Py_INCREF(item);
       PyList_SetItem(list, 1, PyLong_FromLong(0L));
       PyObject_Print(item, stdout, 0);
       Py_DECREF(item);
   }

This is a true story.  An older version of Python contained variants
of this bug and someone spent a considerable amount of time in a C
debugger to figure out why his "__del__()" methods would fail...

二つ目は、借用参照がスレッドに関係しているケースです。通常は、 Python
インタプリタにおける複数のスレッドは、グローバルインタプリタロックがオ
ブジェクト空間全体を保護しているため、互いに邪魔し合うことはありません
。とはいえ、ロックは "Py_BEGIN_ALLOW_THREADS" マクロで一時的に解除した
り、 "Py_END_ALLOW_THREADS" で再獲得したりできます。これらのマクロはブ
ロックの起こる I/O 呼び出しの周囲によく置かれ、 I/O が完了するまでの間
に他のスレッドがプロセッサを利用できるようにします。明らかに、以下の関
数は上の例と似た問題をはらんでいます:

   void
   bug(PyObject *list)
   {
       PyObject *item = PyList_GetItem(list, 0);
       Py_BEGIN_ALLOW_THREADS
       ...some blocking I/O call...
       Py_END_ALLOW_THREADS
       PyObject_Print(item, stdout, 0); /* BUG! */
   }


1.10.4. NULL ポインタ
---------------------

一般論として、オブジェクトへの参照を引数にとる関数はユーザが "NULL" ポ
インタを渡すとは予想しておらず、渡そうとするとコアダンプになる (か、あ
とでコアダンプを引き起こす) ことでしょう。一方、オブジェクトへの参照を
返すような関数は一般に、例外の発生を示す場合にのみ "NULL" を返します。
引数に対して "NULL" テストを行わない理由は、関数はしばしば受け取ったオ
ブジェクトを他の関数へと引き渡すからです --- 各々の関数が "NULL" テス
トを行えば、冗長なテストが大量に行われ、コードはより低速に動くことにな
ります。

従って、 "NULL" のテストはオブジェクトの "発生源"、すなわち値が "NULL"
になるかもしれないポインタを受け取ったときだけにしましょう。
"malloc()" や、例外を送出する可能性のある関数がその例です。

マクロ "Py_INCREF()" および "Py_DECREF()" は "NULL" ポインタのチェック
を行いません --- しかし、これらのマクロの変化形である "Py_XINCREF()"
および "Py_XDECREF()" はチェックを行います。

特定のオブジェクト型について調べるマクロ ("Pytype_Check()") は *NULL*
ポインタのチェックを行いません --- 繰り返しますが、様々な異なる型を想
定してオブジェクトの型を調べる際には、こうしたマクロを続けて呼び出す必
要があるので、個別に "NULL" ポインタのチェックをすると冗長なテストにな
ってしまうのです。型を調べるマクロには、 "NULL" チェックを行う変化形は
ありません。

Python から C 関数を呼び出す機構は、C 関数に渡される引数リスト (例でい
うところの "args") が決して "NULL" にならないよう保証しています --- 実
際には、常にタプル型になるよう保証しています。[4]

"NULL" ポインタを Python ユーザレベルに "逃がし" てしまうと、深刻なエ
ラーを引き起こします。


1.11. C++での拡張モジュール作成
===============================

C++でも拡張モジュールは作成できます。ただしいくつか制限があります。メ
インプログラム (Python インタプリタ) は C コンパイラでコンパイルされリ
ンクされているので、グローバル変数や静的オブジェクトをコンストラクタで
作成できません。メインプログラムが C++ コンパイラでリンクされているな
らこれは問題ではありません。 Python インタプリタから呼び出される関数 (
特にモジュール初期化関数) は、 "extern "C"" を使って宣言しなければなり
ません。また、Python ヘッダファイルを "extern "C" {...}" に入れる必要
はありません--- シンボル "__cplusplus" (最近の C++ コンパイラは全てこ
のシンボルを定義しています) が定義されているときに "extern "C" {...}"
が行われるように、ヘッダファイル内にすでに書かれているからです。


1.12. 拡張モジュールに C API を提供する
=======================================

多くの拡張モジュールは単に Python から使える新たな関数や型を提供するだ
けですが、時に拡張モジュール内のコードが他の拡張モジュールでも便利なこ
とがあります。例えば、あるモジュールでは順序概念のないリストのように動
作する "コレクション (collection)" クラスを実装しているかもしれません
。ちょうどリストを生成したり操作したりできる C API を備えた標準の
Python リスト型のように、この新たなコレクション型も他の拡張モジュール
から直接操作できるようにするには一連の C 関数を持っていなければなりま
せん。

一見するとこれは簡単なこと: 単に関数を (もちろん "static" などとは宣言
せずに) 書いて、適切なヘッダファイルを提供し、C API を書けばよいだけ、
に思えます。そして実際のところ、全ての拡張モジュールが Python インタプ
リタに常に静的にリンクされている場合にはうまく動作します。ところがモジ
ュールが共有ライブラリの場合には、一つのモジュールで定義されているシン
ボルが他のモジュールから不可視なことがあります。可視性の詳細はオペレー
ティングシステムによります; あるシステムは Python インタプリタと全ての
拡張モジュール用に単一のグローバルな名前空間を用意しています (例えば
Windows)。別のシステムはモジュールのリンク時に取り込まれるシンボルを明
示的に指定する必要があります (AIX がその一例です)、また別のシステム (
ほとんどの Unix) では、違った戦略を選択肢として提供しています。そして
、たとえシンボルがグローバル変数として可視であっても、呼び出したい関数
の入ったモジュールがまだロードされていないことだってあります!

従って、可搬性の点からシンボルの可視性には何ら仮定をしてはならないこと
になります。つまり拡張モジュール中の全てのシンボルは "static" と宣言せ
ねばなりません。例外はモジュールの初期化関数で、これは (モジュールのメ
ソッドテーブルと初期化関数 で述べたように) 他の拡張モジュールとの間で
名前が衝突するのを避けるためです。また、他の拡張モジュールからアクセス
を *受けるべきではない* シンボルは別のやり方で公開せねばなりません。

Python はある拡張モジュールの C レベルの情報 (ポインタ) を別のモジュー
ルに渡すための特殊な機構: Capsule (カプセル)を提供しています。 Capsule
はポインタ (void*) を記憶する Python のデータ型です。 Capsule は C API
を介してのみ生成したりアクセスしたりできますが、他の Python オブジェク
トと同じように受け渡しできます。とりわけ、Capsule は拡張モジュールの名
前空間内にある名前に代入できます。他の拡張モジュールはこのモジュールを
import でき、次に名前を取得し、最後にCapsule へのポインタを取得します
。

拡張モジュールの C API を公開するために、様々な方法で Capsule が使われ
ます。各関数を1つのオブジェクトに入れたり、全ての C API のポインタ配列
を Capsule に入れることができます。そして、ポインタに対する保存や取得
といった様々な作業は、コードを提供しているモジュールとクライアントモジ
ュールとの間では異なる方法で分散できます。

どの方法を選ぶにしても、 Capsule の name を正しく設定することは重要で
す。 "PyCapsule_New()" は name 引数 (const char*) を取ります。 "NULL"
を name に渡すことも許可されていますが、 name を設定することを強く推奨
します。正しく名前を付けられた Capsule はある程度の実行時型安全性を持
ちます。名前を付けられていない Capsule を他の Capsule と区別する現実的
な方法はありません。

特に、 C API を公開するための Capsule には次のルールに従った名前を付け
るべきです:

   modulename.attributename

"PyCapsule_Import()" という便利関数は、 Capsule の名前がこのルールに一
致しているときにのみ、簡単に Capsule 経由で公開されている C API をロー
ドすることができます。この挙動により、 C API のユーザーが、確実に正し
い C API を格納している Capsule をロードできたことを確かめることができ
ます。

以下の例では、名前を公開するモジュールの作者にほとんどの負荷が掛かりま
すが、よく使われるライブラリを作る際に適切なアプローチを実演します。こ
のアプローチでは、全ての C API ポインタ (例中では一つだけですが!) を、
Capsule の値となる void ポインタの配列に保存します。拡張モジュールに対
応するヘッダファイルは、モジュールの import と C API ポインタを取得す
るよう手配するマクロを提供します; クライアントモジュールは、C API にア
クセスする前にこのマクロを呼ぶだけです。

The exporting module is a modification of the "spam" module from
section 簡単な例. The function "spam.system()" does not call the C
library function "system()" directly, but a function
"PySpam_System()", which would of course do something more complicated
in reality (such as adding "spam" to every command). This function
"PySpam_System()" is also exported to other extension modules.

The function "PySpam_System()" is a plain C function, declared
"static" like everything else:

   static int
   PySpam_System(const char *command)
   {
       return system(command);
   }

The function "spam_system()" is modified in a trivial way:

   static PyObject *
   spam_system(PyObject *self, PyObject *args)
   {
       const char *command;
       int sts;

       if (!PyArg_ParseTuple(args, "s", &command))
           return NULL;
       sts = PySpam_System(command);
       return PyLong_FromLong(sts);
   }

モジュールの先頭にある以下の行

   #include <Python.h>

の直後に、以下の二行を必ず追加してください:

   #define SPAM_MODULE
   #include "spammodule.h"

"#define" は、ファイル "spammodule.h" をインクルードしているのが名前を
公開する側のモジュールであって、クライアントモジュールではないことをヘ
ッダファイルに教えるために使われます。最後に、モジュールの初期化関数は
C API のポインタ配列を初期化するよう手配しなければなりません:

   PyMODINIT_FUNC
   PyInit_spam(void)
   {
       PyObject *m;
       static void *PySpam_API[PySpam_API_pointers];
       PyObject *c_api_object;

       m = PyModule_Create(&spammodule);
       if (m == NULL)
           return NULL;

       /* Initialize the C API pointer array */
       PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;

       /* Create a Capsule containing the API pointer array's address */
       c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL);

       if (PyModule_Add(m, "_C_API", c_api_object) < 0) {
           Py_DECREF(m);
           return NULL;
       }

       return m;
   }

Note that "PySpam_API" is declared "static"; otherwise the pointer
array would disappear when "PyInit_spam()" terminates!

からくりの大部分はヘッダファイル "spammodule.h" 内にあり、以下のように
なっています:

   #ifndef Py_SPAMMODULE_H
   #define Py_SPAMMODULE_H
   #ifdef __cplusplus
   extern "C" {
   #endif

   /* Header file for spammodule */

   /* C API functions */
   #define PySpam_System_NUM 0
   #define PySpam_System_RETURN int
   #define PySpam_System_PROTO (const char *command)

   /* Total number of C API pointers */
   #define PySpam_API_pointers 1


   #ifdef SPAM_MODULE
   /* This section is used when compiling spammodule.c */

   static PySpam_System_RETURN PySpam_System PySpam_System_PROTO;

   #else
   /* This section is used in modules that use spammodule's API */

   static void **PySpam_API;

   #define PySpam_System \
    (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])

   /* Return -1 on error, 0 on success.
    * PyCapsule_Import will set an exception if there's an error.
    */
   static int
   import_spam(void)
   {
       PySpam_API = (void **)PyCapsule_Import("spam._C_API", 0);
       return (PySpam_API != NULL) ? 0 : -1;
   }

   #endif

   #ifdef __cplusplus
   }
   #endif

   #endif /* !defined(Py_SPAMMODULE_H) */

All that a client module must do in order to have access to the
function "PySpam_System()" is to call the function (or rather macro)
"import_spam()" in its initialization function:

   PyMODINIT_FUNC
   PyInit_client(void)
   {
       PyObject *m;

       m = PyModule_Create(&clientmodule);
       if (m == NULL)
           return NULL;
       if (import_spam() < 0)
           return NULL;
       /* additional initialization can happen here */
       return m;
   }

このアプローチの主要な欠点は、 "spammodule.h" がやや難解になるというこ
とです。とはいえ、各関数の基本的な構成は公開されるものと同じなので、書
き方を一度だけ学べばすみます。

最後に、Capsule は、自身に保存されているポインタをメモリ確保したり解放
したりする際に特に便利な、もう一つの機能を提供しているということに触れ
ておかねばなりません。詳細は Python/C API リファレンスマニュアルの カ
プセル, および Capsule の実装部分 (Python ソースコード配布物中のファイ
ル "Include/pycapsule.h" および "Objects/pycapsule.c" に述べられていま
す。

-[ 脚注 ]-

[1] この関数へのインターフェースはすでに標準モジュール "os" にあります
    --- この関数を選んだのは、単純で直接的な例を示したいからです。

[2] 参照を "借用する" というメタファは厳密には正しくありません: なぜな
    ら、参照の所有者は依然として参照のコピーを持っているからです。

[3] 参照カウントが 1 以上かどうか調べる方法は **うまくいきません** ---
    参照カウント自体も解放されたメモリ上にあるため、その領域が他のオブ
    ジェクトに使われている可能性があります!

[4] "旧式の" 呼び出し規約を使っている場合には、この保証は適用されませ
    ん --- 既存のコードにはいまだに旧式の呼び出し規約が多々あります。
