swigを試してみる

パターン認識の授業で、プログラミングの課題がでた。Rubyを使ったら、「この先、Cとかで関数用意するからRubyだと困るよ?」みたいなことをTAに言われた。というわけで、RubyからCの関数を使えるらしいSwigを試してみる。(採点拒否されたら、どないしよ)

インストール

まずは、公式ページからダウンロードする。Mac用のバイナリ(swig)がおいてあるけれど、コマンドラインから使いたいので、ソースコードをダウンロード。

$ tar xvzf swig-1-1.3.29.tar.gz
$ cd swig-1-1.3.29
$ ./configure
$ make
$ sudo make install

(しまった。fink使ったほうが楽だったかもしれん)

C関数とインターフェイス

まずは、適当にCで関数を書く。つい最近、やったのでユークリッドの互除法で。

/* File: gcd.c */
int gcd(int m,int n){
  if(n == 0) return m;
  else return gcd(n,m%n);
}

つぎにSwig用のインターフェイスを書く

/* File:gcd.i */
%module gcd
extern int gcd(int,int);

これをswigに渡してやる。

$ swig -ruby gcd.i
$ ls
gcd.i gcd.c gcd_wrap.c

コンパイル

コンパイルは、Rubyの拡張ライブラリを作るのと同じ手順。つまり、extconf.rbを書いてやればいい。

# File:extconf.rb
require 'mkmf'
create_makefile 'gcd'

これで、カレントディレクトリにあるCソースファイルから、Gcdという拡張ライブラリを作るMakefileができる。

$ ruby extconf.rb
$ make

Rubyから呼んでみる

gcdをrequireすれば、Rubyから使える。

require 'gcd'
Gcd.gcd(14,12) # => 2
Gcd.gcd(15,3)   # => 3