モジュールの作成2010年2月21日 | |
ファイル内容C で Python のモジュールを作ってみましょう。まず、モジュールの名前を決めましょう。まんま "module" とします。これがもつメソッドを決めましょう。ここでは、"Hello" とだけ出力する sayHello() メソッドをもつものとしましょう。つまり、次のようになるようにしたいわけです。 >>> import module >>> module.sayHello() Hello まず、sayHello() の実装は次のようになります。
static PyObject* module_sayHello(PyObject *self, PyObject *args)
{
printf("Hello\n");
return Py_BuildValue("");
}
PyObject は、Python で使われる一般的なオブジェクトを表わす型です。メソッドは引数として self, args を受け取ります。メソッド名はなんでもよい (はず) ですが、わかりやすく "モジュール名_メソッド名" としておきます。Py_BuildValue() は PyObject を作るための関数です。printf() のように文字列でフォーマットを指定してオブジェクトを作ることができますが、ここでは特に返すものはないので、空のオブジェクトを返しています。 PyObject を作るための関数はいろいろあり、たとえば、C の文字列から Python の文字列オブジェクトを作る PyString_FromString() などがあります。詳しくは "Python/C API Reference Manual" を参照してください。 さて、メソッドの情報を格納した配列を用意します。
static PyMethodDef methods[] = {
{"sayHello", module_sayHello, METH_VARARGS, "Say hello."},
{NULL, NULL, 0, NULL}
};
PyMethodDef 構造体の最初のフィールドにはメソッド名をセットします。2 番目はメソッドを実装した関数を指定します。3 番目は関数が受け取る引数の種類で、ここでは self, args を受け取るように指定しています。4 番目はメソッドの説明で、Python の help() で表示される文字列です。配列の最後にあるのは配列の終わりを表わすものです。 モジュールには初期化が必要です。
PyMODINIT_FUNC
initmodule(void)
{
PyObject *m;
m = Py_InitModule("module", methods);
if(m == NULL) return;
}
これはモジュールのインポート時に呼ばれます。初期化の関数の頭には PyMODINIT_FUNC を指定し、関数の名前は "initモジュール名" とする必要があります。Py_InitModule() にモジュール名とモジュールのメソッドの情報を渡してモジュールを初期化しています。 モジュールは、Windows の場合は DLL にする必要があります。ただし名前は "ほにゃらら.dll" ではなく、Python モジュール用に "ほにゃらら.pyd" とします。Makefile の記述は次のようになります。 LDFLAGS = -shared INCLUDES = -I/c/Python26/include LIBS = -L/c/Python26/libs -lpython26 TARGET = module.pyd 作るファイル名を "module.pyd" にし、リンカのオプションに "-shared" を指定しています。 実行してみましょう。 $ python Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import module >>> dir(module) ['__doc__', '__file__', '__name__', '__package__', 'sayHello'] ちゃんとインポートできましたし、sayHello() もあります。
>>> help(module.sayHello)
Help on built-in function sayHello in module module:
sayHello(...)
Say hello.
sayHello() の説明もばっちり表示されました。 >>> module.sayHello() Hello はじめの期待どおりに動きました。 | |
| PENGUINITIS | |