1. Extending Python with C or C++¶

It is quite easy to add new built-in modules to Python, if you know how to program in C. Such extension modules can do two things that can't be done directly in Python: they can implement new built-in object types, and they can call C library functions and system calls.

To support extensions, the Python API (Application Programmers Interface) defines a set of functions, macros and variables that provide access to most aspects of the Python run-time system. The Python API is incorporated in a C source file by including the header "Python.h".

The compilation of an extension module depends on its intended use as well as on your system setup; details are given in later chapters.

泚釈

The C extension interface is specific to CPython, and extension modules do not work on other Python implementations. In many cases, it is possible to avoid writing C extensions and preserve portability to other implementations. For example, if your use case is calling C library functions or system calls, you should consider using the ctypes module or the cffi library rather than writing custom C code. These modules let you write Python code to interface with C code and are more portable between implementations of Python than writing and compiling a C extension module.

1.1. A Simple Example¶

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

Begin by creating a file spammodule.c. (Historically, if a module is called spam, the C file containing its implementation is called spammodule.c; if the module name is very long, like spammify, the module name can be just spammify.c.)

The first two lines of our file can be:

#define PY_SSIZE_T_CLEAN
#include <Python.h>

which pulls in the Python API (you can add a comment describing the purpose of the module and a copyright notice if you like).

泚釈

Since Python may define some pre-processor definitions which affect the standard headers on some systems, you must include Python.h before any standard headers are included.

#define PY_SSIZE_T_CLEAN was used to indicate that Py_ssize_t should be used in some APIs instead of int. It is not necessary since Python 3.13, but we keep it here for backward compatibility. See 文字列ずバッファ for a description of this macro.

All user-visible symbols defined by Python.h have a prefix of Py or PY, except those defined in standard header files.

Tip

For backward compatibility, Python.h includes several standard header files. C extensions should include the standard headers that they use, and should not rely on these implicit includes. If using the limited C API version 3.13 or newer, the implicit includes are:

  • <assert.h>

  • <intrin.h> (on Windows)

  • <inttypes.h>

  • <limits.h>

  • <math.h>

  • <stdarg.h>

  • <wchar.h>

  • <sys/types.h> (if present)

If Py_LIMITED_API is not defined, or is set to version 3.12 or older, the headers below are also included:

  • <ctype.h>

  • <unistd.h> (on POSIX)

If Py_LIMITED_API is not defined, or is set to version 3.10 or older, the headers below are also included:

  • <errno.h>

  • <stdio.h>

  • <stdlib.h>

  • <string.h>

The next thing we add to our module file is the C function that will be called when the Python expression spam.system(string) is evaluated (we'll see shortly how it ends up being called):

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

There is a straightforward translation from the argument list in Python (for example, the single expression "ls -l") to the arguments passed to the C function. The C function always has two arguments, conventionally named self and args.

The self argument points to the module object for module-level functions; for a method it would point to the object instance.

The args argument will be a pointer to a Python tuple object containing the arguments. Each item of the tuple corresponds to an argument in the call's argument list. The arguments are Python objects --- in order to do anything with them in our C function we have to convert them to C values. The function PyArg_ParseTuple() in the Python API checks the argument types and converts them to C values. It uses a template string to determine the required types of the arguments as well as the types of the C variables into which to store the converted values. More about this later.

PyArg_ParseTuple() returns true (nonzero) if all arguments have the right type and its components have been stored in the variables whose addresses are passed. It returns false (zero) if an invalid argument list was passed. In the latter case it also raises an appropriate exception so the calling function can return NULL immediately (as we saw in the example).

1.2. Intermezzo: Errors and Exceptions¶

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.

You can also define a new exception that is unique to your module. The simplest way to do this is to declare a static global object variable at the beginning of the file:

static PyObject *SpamError = NULL;

and initialize it by calling PyErr_NewException() in the module's Py_mod_exec function (spam_module_exec()):

SpamError = PyErr_NewException("spam.error", NULL, NULL);

Since SpamError is a global variable, it will be overwritten every time the module is reinitialized, when the Py_mod_exec function is called.

For now, let's avoid the issue: we will block repeated initialization by raising an ImportError:

static PyObject *SpamError = NULL;

static int
spam_module_exec(PyObject *m)
{
    if (SpamError != NULL) {
        PyErr_SetString(PyExc_ImportError,
                        "cannot initialize spam module more than once");
        return -1;
    }
    SpamError = PyErr_NewException("spam.error", NULL, NULL);
    if (PyModule_AddObjectRef(m, "SpamError", SpamError) < 0) {
        return -1;
    }

    return 0;
}

static PyModuleDef_Slot spam_module_slots[] = {
    {Py_mod_exec, spam_module_exec},
    {0, NULL}
};

static struct PyModuleDef spam_module = {
    .m_base = PyModuleDef_HEAD_INIT,
    .m_name = "spam",
    .m_size = 0,  // non-negative
    .m_slots = spam_module_slots,
};

PyMODINIT_FUNC
PyInit_spam(void)
{
    return PyModuleDef_Init(&spam_module);
}

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.

For now, the Py_DECREF() call to remove this reference is missing. Even when the Python interpreter shuts down, the global SpamError variable will not be garbage-collected. It will "leak". We did, however, ensure that this will happen at most once per process.

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. Back to the Example¶

Going back to our example function, you should now be able to understand this statement:

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

The next statement is a call to the Unix function system(), passing it the string we just got from PyArg_ParseTuple():

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

In this case, it will return an integer object. (Yes, even integers are objects on the heap in Python!)

If you have a C function that returns no useful argument (a function returning void), the corresponding Python function must return None. You need this idiom to do so (which is implemented by the Py_RETURN_NONE macro):

Py_INCREF(Py_None);
return Py_None;

Py_None is the C name for the special Python object None. It is a genuine Python object rather than a NULL pointer, which means "error" in most contexts, as we have seen.

1.4. The Module's Method Table and Initialization Function¶

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 spam_methods[] = {
    ...
    {"system",  spam_system, METH_VARARGS,
     "Execute a shell command."},
    ...
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

Note the third entry (METH_VARARGS). This is a flag telling the interpreter the calling convention to be used for the C function. It should normally always be METH_VARARGS or METH_VARARGS | METH_KEYWORDS; a value of 0 means that an obsolete variant of PyArg_ParseTuple() is used.

When using only METH_VARARGS, the function should expect the Python-level parameters to be passed in as a tuple acceptable for parsing via PyArg_ParseTuple(); more information on this function is provided below.

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.

The method table must be referenced in the module definition structure:

static struct PyModuleDef spam_module = {
    ...
    .m_methods = spam_methods,
    ...
};

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 PyModuleDef_Init(&spam_module);
}

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

PyInit_spam() is called when each interpreter imports its module spam for the first time. (See below for comments about embedding Python.) A pointer to the module definition must be returned via PyModuleDef_Init(), so that the import machinery can create the module and store it in 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);
}

泚釈

If you declare a global variable or a local static one, the module may experience unintended side-effects on re-initialisation, for example when removing entries from sys.modules or importing compiled modules into multiple interpreters within a process (or following a fork() without an intervening exec()). If module state is not yet fully isolated, authors should consider marking the module as having no support for subinterpreters (via Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED).

A more substantial example module is included in the Python source distribution as Modules/xxlimited.c. This file may be used as a template or simply read as an example.

1.5. Compilation and Linkage¶

There are two more things to do before you can use your new extension: compiling and linking it with the Python system. If you use dynamic loading, the details may depend on the style of dynamic loading your system uses; see the chapters about building extension modules (chapter C および C++ 拡匵のビルド) and additional information that pertains only to building on Windows (chapter Windows 䞊での C および C++ 拡匵モゞュヌルのビルド) for more information about this.

If you can't use dynamic loading, or if you want to make your module a permanent part of the Python interpreter, you will have to change the configuration setup and rebuild the interpreter. Luckily, this is very simple on Unix: just place your file (spammodule.c for example) in the Modules/ directory of an unpacked source distribution, add a line to the file Modules/Setup.local describing your file:

spam spammodule.o

を远加しお、トップレベルのディレクトリで make を実行しお、むンタプリタを再ビルドするだけです。 Modules/ サブディレクトリでも make を実行できたすが、前もっお 'make Makefile' を実行しお Makefile を再ビルドしおおかなければならりたせん。(この䜜業は Setup ファむルを倉曎するたびに必芁です。)

モゞュヌルが別のラむブラリずリンクされおいる必芁がある堎合、ラむブラリも蚭定ファむルに列挙できたす。䟋えば以䞋のようにしたす。

spam spammodule.o -lX11

1.6. C から Python 関数を呌び出す¶

So far we have concentrated on making C functions callable from Python. The reverse is also useful: calling Python functions from C. This is especially the case for libraries that support so-called "callback" functions. If a C interface makes use of callbacks, the equivalent Python often needs to provide a callback mechanism to the Python programmer; the implementation will require calling the Python callback functions from a C callback. Other uses are also imaginable.

Fortunately, the Python interpreter is easily called recursively, and there is a standard interface to call a Python function. (If you're interested in how to call the Python parser with a particular string as input, see 超高氎準レむダ.)

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 Module's Method Table and Initialization Function. 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. 拡匵モゞュヌル関数でのパラメタ展開¶

The PyArg_ParseTuple() function is declared as follows:

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 keywdarg_module = {
    .m_base = PyModuleDef_HEAD_INIT,
    .m_name = "keywdarg",
    .m_size = 0,
    .m_methods = keywdarg_methods,
};

PyMODINIT_FUNC
PyInit_keywdarg(void)
{
    return PyModuleDef_Init(&keywdarg_module);
}

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) ず呌ばれる手法です。参照カりント法の原理は簡単です: 党おのオブゞェクトにはカりンタがあり、オブゞェクトに察する参照がどこかに保存されたらカりンタをむンクリメントし、オブゞェクトに察する参照が削陀されたらデクリメントしたす。カりンタがれロになったら、オブゞェクトぞの最埌の参照が削陀されたこずになり、オブゞェクトは解攟されたす。

An alternative strategy is called automatic garbage collection. (Sometimes, reference counting is also referred to as a garbage collection strategy, hence the use of "automatic" to distinguish the two.) The big advantage of automatic garbage collection is that the user doesn't need to call free() explicitly. (Another claimed advantage is an improvement in speed or memory usage --- this is no hard fact however.) The disadvantage is that for C, there is no truly portable automatic garbage collector, while reference counting can be implemented portably (as long as the functions malloc() and free() are available --- which the C Standard guarantees). Maybe some day a sufficiently portable automatic garbage collector will be available for C. Until then, we'll have to live with reference counts.

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() を呌び出す、ずいう䞉぀の方法がありたす。所有参照を凊理し忘れるず、メモリリヌクを匕き起こしたす。

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() は新たな所有参照を生成し、参照の所有者が担うべき党おの責任を課したす (぀たり、新たな参照の所有者は、以前の所有者ず同様、参照の攟棄を適切に行わねばなりたせん)。

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. Internally, PyList_SetItem() calls Py_DECREF() on the replaced item, which invokes replaced item's corresponding tp_dealloc function. During deallocation, tp_dealloc calls tp_finalize, which is mapped to the __del__() method for class instances (see PEP 442). This entire sequence happens synchronously within the PyList_SetItem() call.

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

The second case of problems with a borrowed reference is a variant involving threads. Normally, multiple threads in the Python interpreter can't get in each other's way, because there is a global lock protecting Python's entire object space. However, it is possible to temporarily release this lock using the macro Py_BEGIN_ALLOW_THREADS, and to re-acquire it using Py_END_ALLOW_THREADS. This is common around blocking I/O calls, to let other threads use the processor while waiting for the I/O to complete. Obviously, the following function has the same problem as the previous one:

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 チェックを行う倉化圢はありたせん。

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 ナヌザレベルに "逃がし" おしたうず、深刻な゚ラヌを匕き起こしたす。

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) では、違った戊略を遞択肢ずしお提䟛しおいたす。そしお、たずえシンボルがグロヌバル倉数ずしお可芖であっおも、呌び出したい関数の入ったモゞュヌルがただロヌドされおいないこずだっおありたす!

Portability therefore requires not to make any assumptions about symbol visibility. This means that all symbols in extension modules should be declared static, except for the module's initialization function, in order to avoid name clashes with other extension modules (as discussed in section The Module's Method Table and Initialization Function). And it means that symbols that should be accessible from other extension modules must be exported in a different way.

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 A Simple Example. 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"

The #define is used to tell the header file that it is being included in the exporting module, not a client module. Finally, the module's mod_exec function must take care of initializing the C API pointer array:

static int
spam_module_exec(PyObject *m)
{
    static void *PySpam_API[PySpam_API_pointers];
    PyObject *c_api_object;

    /* 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) {
        return -1;
    }

    return 0;
}

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 mod_exec function:

static int
client_module_exec(PyObject *m)
{
    if (import_spam() < 0) {
        return -1;
    }
    /* additional initialization can happen here */
    return 0;
}

このアプロヌチの䞻芁な欠点は、 spammodule.h がやや難解になるずいうこずです。ずはいえ、各関数の基本的な構成は公開されるものず同じなので、曞き方を䞀床だけ孊べばすみたす。

Finally it should be mentioned that Capsules offer additional functionality, which is especially useful for memory allocation and deallocation of the pointer stored in a Capsule. The details are described in the Python/C API Reference Manual in the section カプセル and in the implementation of Capsules (files Include/pycapsule.h and Objects/capsule.c in the Python source code distribution).

脚泚