拡張ライブラリチュートリアルをやってみる#4
ラッパーをいちいち手書きすると大変なので,Swig を使うやり方.
整数の足し算
- test5.i
%module test %{ %} extern int add(int a, int b);
これは,
- test モジュールを作成する
- 外部参照する関数 add を使う
ということを宣言しているらしい.そしてこれを使ってラッパーを作成
% swig -ruby test5.i
作成されたファイルは test5_wrap.c で,中身は省略.
|
Ruby の拡張ライブラリなので,extconf.rb を作成する.
- extconf.rb
require 'mkmf' create_makefile('test')
% ruby extconf.rb % make % ruby -r'test' -e'p Test.add(1, 2)' 3
確かに記載しなくていいのは楽ではあるが,中身的に何やってるかわからないのが,ちょっとあれな感じかな.
NArray での要素の掛け算
NArrayを使った例を Swig で.
同じく Swig の入力ファイルから.
- test6.i
%module test %{ #include "narray.h" %} %typemap(ruby,in) (float *NARRAY, int LENGTH){ VALUE na; struct NARRAY *n_na; na = na_cast_object($input, NA_SFLOAT); GetNArray(na, n_na); $1 = (float*)n_na->ptr; $2 = n_na->total; } extern float mul_all(float *NARRAY, int LENGTH);
そしてラッパーの作成とコンパイル,実行.
% swig -ruby test6.i % make % irb >> require 'narray' => true >> require 'test' => true >> Test.mul_all(NArray.sfloat(5).indgen!(1,1)) => 21.0
ん?なぜか答えが合わない.Swig で生成されたラッパーを見ると,どうも mul_all の関数プロトタイプ宣言がない模様.なので,narray.h を include している後に,それを書いておく.
- test6.i
%module test %{ #include "narray.h" float mul_all(float *array, int nx); %} %typemap(ruby,in) (float *NARRAY, int LENGTH){ VALUE na; struct NARRAY *n_na; na = na_cast_object($input, NA_SFLOAT); GetNArray(na, n_na); $1 = (float*)n_na->ptr; $2 = n_na->total; } extern float mul_all(float *NARRAY, int LENGTH);
再度,ラッパーの作成とコンパイル,実行.
% swig -ruby test6.i % make % irb >> require 'narray' => true >> require 'test' => true >> Test.mul_all(NArray.sfloat(5).indgen!(1,1)) => 120.0
ようやく成功.これがわかるのにちょっと時間かかりました.C は難しいなぁ.
あと,やはり Swig の部分がわからない.調べるのもいいが,ひとまずは自力で書いてみることにしよう.