Python: SWIG で C 言語拡張モジュールを作ってみる
SWIG は C/C++ を使ったライブラリのスクリプト言語のバインディングを作りやすくするためのツール。 本来は Python/C API を使って自分でチマチマ書かなきゃいけない C/C++ とスクリプト言語のグルー部分を自動生成してくれる。
まずは SWIG をインストールする。 今回使った環境は OS X なので Homebrew から。
次に C/C++ のソースファイルを用意していく。 今回はシンプルに C 言語で、呼び出す関数もごく単純なものにした。
以下はヘッダファイル。 greet.h という名前で保存しておく。
次にソースファイル。 greet.c という名前で保存する。
#include <stdio.h> void greet(void) { printf("Hello, World!\n"); }
次に SWIG の設定ファイルを用意する。 使用するヘッダや、バインディングを作成する関数を記述する。 greet.i という名前で保存する。
%module greet %{ #include "greet.h" #include <stdio.h> %} extern void greet(void);
設定ファイルを元に SWIG でグルーコードを自動生成する。
$ ls greet.c greet.h greet.i greet.py greet_wrap.c
$ gcc -c greet.c $ gcc -c greet_wrap.c -I /usr/include/python2.7 $ gcc -shared greet.o greet_wrap.o -o _greet.so -l python
$ file _greet.so _greet.so: Mach-O 64-bit dynamically linked shared library x86_64
同じディレクトリで Python の REPL を起動して動作確認してみる。
$ python >>> import greet >>> greet.greet() Hello, World!
ばっちり。
これだけだと使い勝手がイマイチなんで、次は setup.py を書いてパッケージングできるようにする。
#!/usr/bin/env python # -*- coding: utf-8 -*- from setuptools import setup from setuptools import Extension ext_greet = Extension( '_greet', sources=['greet_wrap.c', 'greet.c'], ) if __name__ == '__main__': setup( name='greet', version='0.0.1', description='SWIG Example package', ext_modules=[ext_greet], py_modules=['greet'], )
Setuptools 経由で拡張モジュールをビルドしてみる。
$ python setup.py build_ext $ ls build/lib.macosx-10.10-x86_64-2.7 _greet.so
$ python setup.py install $ pip list | grep greet greet (0.0.1)
$ python >>> import greet >>> greet.greet() Hello, World!