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

C プログラムの書き方を知っているなら、Python に新たな組み込みモジュー
ルを追加するのはきわめて簡単です。この新たなモジュール、拡張モジュール
(*extention 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 コードを書かせてくれます。


簡単な例
========

Let’s create an extension module called "spam" (the favorite food of
Monty Python fans…) and let’s say we want to create a Python interface
to the C library function "system()" [1]. This function takes a null-
terminated character string as argument and returns an integer.  We
want this function to be callable from Python as follows:

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

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

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

   #include <Python.h>

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

注釈: Python は、システムによっては標準ヘッダの定義に影響するような
  プリプ ロセッサ定義を行っているので、 "Python.h" をいずれの標準ヘッ
  ダよりも 前にインクルード *せねばなりません* 。

"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 Py_BuildValue("i", sts);
   }

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

For module functions, the *self* argument is *NULL* or a pointer
selected while initializing the module (see "Py_InitModule4()").  For
a method, it would point to the object instance.

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

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


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

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 a *NULL* pointer).  Exceptions are
stored in a static global variable inside the interpreter; if this
variable is *NULL* no exception has occurred.  A second global
variable stores the 「associated value」 of the exception (the second
argument to "raise").  A third variable contains the stack traceback
in case the error originated in Python code.  These three variables
are the C equivalents of the Python variables "sys.exc_type",
"sys.exc_value" and "sys.exc_traceback" (see the section on module
"sys" in the Python Library Reference).  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_*()" を何度も呼び出す必要
はなく、ともすればエラーの原因に関する情報を失う結果になりがちです: こ
れにより、ほとんどの操作が様々な理由から失敗するかもしれません)

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

Every failing "malloc()" call must be turned into an exception — the
direct caller of "malloc()" (or "realloc()") must call
"PyErr_NoMemory()" and return a failure indicator itself.  All the
object-creating functions (for example, "PyInt_FromLong()") already do
this, so this note is only relevant to those who call "malloc()"
directly.

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

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

どの例外を返すかの選択は、ユーザに完全にゆだねられます。
"PyExc_ZeroDivisionError" のように、全ての組み込みの Python 例外には対
応する宣言済みの C オブジェクトがあり、直接利用できます。もちろん、例
外の選択は賢く行わねばなりません — ファイルが開けなかったことを表すの
に "PyExc_TypeError" を使ったりはしないでください (この場合はおそらく
"PyExc_IOError" の方にすべきでしょう)。引数リストに問題がある場合には
、 "PyArg_ParseTuple()" はたいてい "PyExc_TypeError" を送出します。引
数の値が特定の範囲を超えていたり、その他の満たすべき条件を満たさなかっ
た場合には、 "PyExc_ValueError" が適切です。

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

   static PyObject *SpamError;

and initialize it in your module’s initialization function
("initspam()") with an exception object (leaving out the error
checking for now):

   PyMODINIT_FUNC
   initspam(void)
   {
       PyObject *m;

       m = Py_InitModule("spam", SpamMethods);
       if (m == NULL)
           return;

       SpamError = PyErr_NewException("spam.error", NULL, NULL);
       Py_INCREF(SpamError);
       PyModule_AddObject(m, "error", SpamError);
   }

Python レベルでの例外オブジェクトの名前は "spam.error" になることに注
意してください。 "PyErr_NewException()" 関数は、 組み込み例外 で述べら
れている "Exception" クラスを基底クラスに持つ例外クラスも作成できます
(*NULL* の代わりに他のクラスを渡した場合は別です)。

"SpamError" 変数は、新たに生成された例外クラスへの参照を維持することに
も注意してください; これは意図的な仕様です! 外部のコードが例外オブジェ
クトをモジュールから除去できるため、モジュールから新たに作成した例外ク
ラスが見えなくなり、 "SpamError" がぶら下がりポインタ (dangling
pointer) になってしまわないようにするために、クラスに対する参照を所有
しておかねばなりません。もし "SpamError" がぶら下がりポインタになって
しまうと、 C コードが例外を送出しようとしたときにコアダンプや意図しな
い副作用を引き起こすことがあります。

この例にある、関数の戻り値型に "PyMODINIT_FUNC" を使う方法については後
で議論します。

"PyErr_SetString()" を次のように呼び出すと、拡張モジュールで例外
"spam.error" を送出することができます:

   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);
   }


例に戻る
========

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

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

この実行文は、 "PyArg_ParseTuple()" がセットする例外によって、引数リス
トに何らかのエラーが生じたときに *NULL* (オブジェクトへのポインタを返
すタイプの関数におけるエラー標示値) を返します。エラーでなければ、引数
として与えた文字列値はローカルな変数 "command" にコピーされています。
この操作はポインタ代入であり、ポインタが指している文字列に対して変更が
行われるとは想定されていません (従って、標準 C では、変数 "command" は
"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 "Py_BuildValue()",
which is something like the inverse of "PyArg_ParseTuple()": it takes
a format string and an arbitrary number of C values, and returns a new
Python object. More info on "Py_BuildValue()" is given later.

   return Py_BuildValue("i", sts);

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

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

   Py_INCREF(Py_None);
   return Py_None;

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


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

さて、前に約束したように、 "spam_system()" を Python プログラムからど
うやって呼び出すかをこれから示します。まずは、関数名とアドレスを 「メ
ソッドテーブル (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()" が受理できるタプルの形式で渡されるものと想定しな
ければなりません; この関数についての詳細は下で説明します。

関数にキーワード引数が渡されることになっているのなら、第三フィールドに
"METH_KEYWORDS" ビットをセットできます。この場合、C 関数は第三引数に
"PyObject *" を受理するようにせねばなりません。このオブジェクトは、キ
ーワード引数の辞書になります。こうした関数で引数を解釈するには、
"PyArg_ParseTupleAndKeywords()" を使ってください。

The method table must be passed to the interpreter in the module’s
initialization function.  The initialization function must be named
"initname()", where *name* is the name of the module, and should be
the only non-"static" item defined in the module file:

   PyMODINIT_FUNC
   initspam(void)
   {
       (void) Py_InitModule("spam", SpamMethods);
   }

Note that PyMODINIT_FUNC declares the function as "void" 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,
"initspam()" is called. (See below for comments about embedding
Python.) It calls "Py_InitModule()", which creates a 「module object」
(which is inserted in the dictionary "sys.modules" under the key
""spam""), and inserts built-in function objects into the newly
created module based upon the table (an array of "PyMethodDef"
structures) that was passed as its second argument. "Py_InitModule()"
returns a pointer to the module object that it creates (which is
unused here).  It may abort with a fatal error for certain errors, or
return *NULL* if the module could not be initialized satisfactorily.

When embedding Python, the "initspam()" function is not called
automatically unless there’s an entry in the "_PyImport_Inittab"
table. The easiest way to handle this is to statically initialize your
statically-linked modules by directly calling "initspam()" after the
call to "Py_Initialize()":

   int
   main(int argc, char *argv[])
   {
       /* Pass argv[0] to the Python interpreter */
       Py_SetProgramName(argv[0]);

       /* Initialize the Python interpreter.  Required. */
       Py_Initialize();

       /* Add a static module */
       initspam();

       ...

An example may be found in the file "Demo/embed/demo.c" in the Python
source distribution.

注釈: Removing entries from "sys.modules" or importing compiled
  modules into multiple interpreters within a process (or following a
  "fork()" without an intervening "exec()") can create problems for
  some extension modules. Extension module authors should exercise
  caution when initializing internal data structures. Note also that
  the "reload()" function can be used with extension modules, and will
  call the module initialization function ("initspam()" in the
  example), but will not load the module again if it was loaded from a
  dynamically loadable object file (".so" on Unix, ".dll" on Windows).

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


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

新しい拡張モジュールを使えるようになるまで、まだ二つの作業: コンパイル
と、Python システムへのリンク、が残っています。動的読み込み (dynamic
loading) を使っているのなら、作業の詳細は自分のシステムが使っている動
的読み込みの形式によって変わるかもしれません; 詳しくは、拡張モジュール
のビルドに関する章 (distutils による 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


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;
   }

この関数は "METH_VARARGS" フラグを使ってインタプリタに登録せねばなりま
せん; "METH_VARARGS" フラグについては、 モジュールのメソッドテーブルと
初期化関数 で説明しています。 "PyArg_ParseTuple()" 関数とその引数につ
いては、 拡張モジュール関数でのパラメタ展開 に記述しています。

"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);


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

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

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

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

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

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

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

   int ok;
   int i, j;
   long k, l;
   const char *s;
   int 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) */
   }


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

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

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

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

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

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

   #include "Python.h"

   static PyObject *
   keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)
   {
       int voltage;
       char *state = "a stiff";
       char *action = "voom";
       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_INCREF(Py_None);

       return Py_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)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
        "Print a lovely skit to standard output."},
       {NULL, NULL, 0, NULL}   /* sentinel */
   };

   void
   initkeywdarg(void)
   {
     /* Create the module and add the functions */
     Py_InitModule("keywdarg", keywdarg_methods);
   }


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

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

   PyObject *Py_BuildValue(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("ss", "hello", "world")    ('hello', 'world')
   Py_BuildValue("s#", "hello", 4)          '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))


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

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

"malloc()" が確保する全てのメモリブロックは、最終的には "free()" を厳
密に一度だけ呼び出して利用可能メモリのプールに戻さねばなりません。そこ
で、適切な時に "free()" を呼び出すことが重要になります。あるメモリブロ
ックに対して、 "free()" を呼ばなかったにもかかわらずそのアドレスを忘却
してしまうと、ブロックが占有しているメモリはプログラムが終了するまで再
利用できなくなります。これはメモリリーク(*memory leak*) と呼ばれていま
す。逆に、プログラムがあるメモリブロックに対して "free()" を呼んでおき
ながら、そのブロックを使い続けようとすると、別の "malloc()" 呼び出しに
よって行われるブロックの再利用と衝突を起こします。これは解放済みメモリ
の使用 (*using freed memory*) と呼ばれます。これは初期化されていないデ
ータに対する参照と同様のよくない結果 — コアダンプ、誤った参照、不可解
なクラッシュ — を引き起こします。

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

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

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

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

The cycle detector is able to detect garbage cycles and can reclaim
them so long as there are no finalizers implemented in Python
("__del__()" methods). When there are such finalizers, the detector
exposes the cycles through the "gc" module (specifically, the
"garbage" variable in that module). The "gc" module also exposes a way
to run the detector (the "collect()" function), as well as
configuration interfaces and the ability to disable the detector at
runtime.  The cycle detector is considered an optional component;
though it is included by default, it can be disabled at build time
using the "--without-cycle-gc" option to the **configure** script on
Unix platforms (including Mac OS X) or by removing the definition of
"WITH_CYCLE_GC" in the "pyconfig.h" header on other platforms.  If the
cycle detector is disabled in this way, the "gc" module will not be
available.


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()" を呼び出す、という三つの方法があります。所有参照
を処理し忘れると、メモリリークを引き起こします。

It is also possible to *borrow* [2] a reference to an object.  The
borrower of a reference should not call "Py_DECREF()".  The borrower
must not hold on to the object longer than the owner from which it was
borrowed. Using a borrowed reference after the owner has disposed of
it risks using freed memory and should be avoided completely [3].

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

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


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

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

Most functions that return a reference to an object pass on ownership
with the reference.  In particular, all functions whose function it is
to create a new object, such as "PyInt_FromLong()" and
"Py_BuildValue()", pass ownership to the receiver.  Even if the object
is not actually new, you still receive ownership of a new reference to
that object.  For instance, "PyInt_FromLong()" maintains a cache of
popular values and can return a reference to a cached item.

"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 関数が返す参照は所有参照でなければなりません
— 所有権は関数から呼び出し側へと委譲されます。


薄氷
----

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

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

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

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

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

"PyList_SetItem()" の処理の流れを追跡してみましょう。リストは全ての要
素に対して参照を所有しているので、要素 1 を置き換えると、以前の要素 1
を放棄します。ここで、以前の要素 1 がユーザ定義クラスのインスタンスで
あり、さらにこのクラスが "__del__()" メソッドを定義していると仮定しま
しょう。このクラスインスタンスの参照カウントが 1 だった場合、リストが
参照を放棄すると、インスタンスの "__del__()" メソッドが呼び出されます
。

クラスは Python で書かれているので、 "__del__()" は任意の Python コー
ドを実行できます。この "__del__()" が "bug()" における "item" に何か不
正なことをしているのでしょうか? その通り! "bug()" に渡したリストが
"__del__()" メソッドから操作できるとすると、 "del list[0]" の効果を持
つような文を実行できてしまいます。もしこの操作で "list[0]" に対する最
後の参照が放棄されてしまうと、 "list[0]" に関連付けられていたメモリは
解放され、結果的に "item" は無効な値になってしまいます。

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

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

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

これは実際にあった話です。以前のバージョンの Python には、このバグの一
種が潜んでいて、 "__del__()" メソッドがどうしてうまく動かないのかを調
べるために C デバッガで相当時間を費やした人がいました…

二つ目は、借用参照がスレッドに関係しているケースです。通常は、 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! */
   }


NULL ポインタ
-------------

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

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

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

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

The C function calling mechanism guarantees that the argument list
passed to C functions ("args" in the examples) is never *NULL* — in
fact it guarantees that it is always a tuple [4].

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


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

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


拡張モジュールに 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 に
アクセスする前にこのマクロを呼ぶだけです。

名前を公開する側のモジュールは、 簡単な例 節の "spam" モジュールを修正
したものです。関数 "spam.system()" は C ライブラリ関数 "system()" を直
接呼び出さず、 "PySpam_System()" を呼び出します。この関数はもちろん、
実際には (全てのコマンドに 「spam」 を付けるといったような) より込み入
った処理を行います。この関数 "PySpam_System()" はまた、他の拡張モジュ
ールにも公開されます。

関数 "PySpam_System()" は、他の全ての関数と同様に "static" で宣言され
た通常の C 関数です:

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

"spam_system()" には取るに足らない変更が施されています:

   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 Py_BuildValue("i", sts);
   }

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

   #include "Python.h"

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

   #define SPAM_MODULE
   #include "spammodule.h"

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

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

       m = Py_InitModule("spam", SpamMethods);
       if (m == NULL)
           return;

       /* 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 (c_api_object != NULL)
           PyModule_AddObject(m, "_C_API", c_api_object);
   }

Note that "PySpam_API" is declared "static"; otherwise the pointer
array would disappear when "initspam()" 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) */

"PySpam_System()" へのアクセス手段を得るためにクライアントモジュール側
がしなければならないことは、初期化関数内での "import_spam()" 関数 (ま
たはマクロ) の呼び出しです:

   PyMODINIT_FUNC
   initclient(void)
   {
       PyObject *m;

       m = Py_InitModule("client", ClientMethods);
       if (m == NULL)
           return;
       if (import_spam() < 0)
           return;
       /* additional initialization can happen here */
   }

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

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

-[ 脚注 ]-

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

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

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

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