拡張ライブラリチュートリアルをやってみる#2
続き.
数値のやりとり
整数の加算をやってみる.
処理実体
- add.c
int add(a, b) int a, b; { return(a + b); }
int を 2 つ受け取って加算した結果を int で返す.コードに問題ないかをちょっとテストのために実行してみる
- main.c
#include <stdio.h> int add(int a, int b); int main() { int a, b; a = 1; b = 2; printf("%d + %d = %d\n", a, b, add(a, b)); }
% cc -o add add.c main.c % ./add 1 + 2 = 3
まあ普通に実行される.
C と Ruby の接続
Ruby では数値ですらオブジェクトなので, C の int 型に変換する必要がある.それをやってくれるのが,以下のマクロ・関数らしい.
- FIX2INT
- Ruby オブジェクトを int 型へ変換する
- NUM2INT
- Numeric かどうかをチェックしてから int 型へと変換する.Numeric でない場合は例外を吐く.
- INT2FIX
- signed int(31bit) を Ruby の Fixnum へと変換する.
- INT2NUM
- int を Ruby の Interger へ変換する.桁あふれの場合は Bignum へと自動拡張して変換する.
- NUM2DBL
- Numeric かどうかをチェックしてから double 型へと変換する.Numeric でない場合は例外を吐く.
- rb_float_new(float)
- float/double 型の実数を Float 型へと変換する.
そしてこれを使ってラッパーを作る.
- test2.c
#include "ruby.h" int add(int a, int b); VALUE wrap_add(self, aa, bb) VALUE self, aa, bb; { int a, b, result; a = FIX2INT(aa); // FIX2INT によって,VALUE 型構造体を int 型へ変換する b = FIX2INT(bb); // 同上 result = add(a, b); return INT2FIX(result); // INT2FIX によって,int 型を VALUE 型構造体へ変換する } void Init_test() { VALUE module; module = rb_define_module("Test"); // Test モジュールを生成する rb_define_module_function(module, "add", wrap_add, 2); // module(Test モジュール) に add メソッドを,引数の数を2として登録する }