More Related Content
Similar to はじめてのRuby拡張ライブラリ
Similar to はじめてのRuby拡張ライブラリ (20)
More from Masahiro Tomita
More from Masahiro Tomita (20)
はじめてのRuby拡張ライブラリ
- 1. はじめてのRuby拡
張ライブラリ
とみたまさひろ
2010-05-22
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 2. 自己紹介
✓ とみた まさひろ
✓ プログラマー
✓ mailto:tommy@tmtm.org
✓ http://d.hatena.ne.jp/tmtms
✓ http://twitter.com/tmtms
1/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 3. 自己紹介
✓ 日本Rubyの会
✓ 日本MySQLユーザ会
✓ Ruby/MySQL ライブラリ
✓ Ruby歴, MySQL歴 十数年
2/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 4. 自己紹介
こんな本書きました
3/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 5. NSEG #1 で
4/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 6. Ruby拡張
ライブラリ
5/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 7. Ruby
は遅い
はじめてのRuby拡張ライブラリ
6/33
Powered by Rabbit 0.6.4
- 8. こんなに遅い
7/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 10. Cのライブラ
リをRubyか
ら使いたい 9/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 11. ということ
で拡張ライ
ブラリ
はじめてのRuby拡張ライブラリ
10/33
Powered by Rabbit 0.6.4
- 12. 通常のライブラリ
✓ Ruby で書かれている
✓ 拡張子 .rb
✓ require 'hoge'
✓ require 'hoge.rb'
11/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 13. 拡張ライブラリ
✓ C で書かれている
✓ 拡張子 .so (Linux の場合)
✓ require 'hoge' (.rb が優先)
✓ require 'hoge.o'
✓ require 'hoge.so'
12/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 14. 作り方
13/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 15. 専用ディレクトリが必要
$ ls hoge/
extconf.rb
hoge.c
14/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 16. hoge.c
拡張ライブラリ本体
/* require 'hoge' 時に呼ばれる関数 */
void Init_hoge(void)
{
puts("Hello");
}
15/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 17. extconf.rb
拡張ライブラリを作るための
Makefile を作る
require 'mkmf'
create_makefile 'hoge'
16/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 18. コンパイル&実行
$ ruby ./extconf.rb
creating Makefile
$ make
...
$ ls
Makefile hoge.c hoge.so
extconf.rb hoge.o
$ ruby -e 'require "hoge"'
Hello
17/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 19. クラス&メソッド
#include <ruby.h>
VALUE cHoge; /* Hoge クラス */
/* Hoge#xxx メソッド実行時に呼ばれる関数 */
static VALUE hoge_xxx(VALUE obj)
{
...
}
/* require 'hoge' 時に呼ばれる関数 */
void Init_hoge(void)
{
/* Object クラスを継承した Hoge クラスを作成 */
cHoge = rb_define_class("Hoge", rb_cObject);
/* 引数0個のメソッド xxx を定義 */
rb_define_method(cHoge, "xxx", hoge_xxx, 0);
}
18/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 20. メソッド引数
/* 引数なし */
rb_define_method(cHoge, "xxx0", hoge_xxx0, 0);
static VALUE hoge_xxx0(VALUE obj);
/* 引数1個 */
rb_define_method(cHoge, "xxx1", hoge_xxx1, 1);
static VALUE hoge_xxx1(VALUE obj, VALUE arg);
/* 引数2個 */
rb_define_method(cHoge, "xxx2", hoge_xxx2, 2);
static VALUE hoge_xxx2(VALUE obj, VALUE arg1, VALUE arg2);
19/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 21. 不定個引数
rb_define_method(cHoge, "xxxx", hoge_xxxx, -1);
...
/* def xxxx(arg1, arg2=nil, arg3=nil) とほぼ同じ */
static VALUE hoge_xxxx(int argc, VALUE *argv, VALUE obj)
{
VALUE arg1, arg2, arg3;
/* 自分で引数を数えてもいいけど、専用関数あり */
/* 必須1個、オプション2個 */
rb_scan_args(argc, argv, "12", &arg1, &arg2, &arg3);
}
/* def xxxx(arg1, arg2=nil, *other) とほぼ同じ */
static VALUE hoge_xxxx(int argc, VALUE *argv, VALUE obj)
{
VALUE arg1, arg2;
/* 必須1個、オプション1個、それ以上はここでは無視 */
rb_scan_args(argc, argv, "11*", &arg1, &arg2);
/* argv[2]〜argv[argc-1] が残りの引数 */
}
20/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 22. データ変換
RubyからC
NUM2INT(n) -> int
NUM2LONG(n) -> long
NUM2DBL(n) -> double
RSTRING_PTR(s) -> char*
RSTRING_LEN(s) -> 文字列の長さ
RARRAY_PTR(a) -> VALUE*
RARRAY_LEN(a) -> 配列の要素数
21/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 23. データ変換
CからRuby
INT2NUM(int) -> Fixnum or Bignum
LONG2NUM(long) -> Fixnum or Bignum
DBL2NUM(double) -> Float
rb_str_new(char*, long) -> String
rb_ary_new() -> 空の配列
rb_ary_new3(long, ...) -> n個の要素を持つ配列
22/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 24. 真偽値
Ruby C
true Qtrue
false Qfalse
nil Qnil
23/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 25. 定義済みクラス
Ruby C
Object rb_cObject
Module rb_cModule
Class rb_cClass
String rb_cString
Array rb_cArray
24/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 26. Rubyオブジェクトの操作
str.concat("hoge")
→ rb_str_cat(str, "hoge", 4)
ary[n]
→ rb_ary_at(ary, n)
hash[key]
→ rb_hash_aref(hash, key)
Hoge::Fuga → Hoge.const_get(:Fuga)
→ rb_const_get(cHoge, rb_intern("Fuga"))
obj.instance_variable_get(:@name)
→ rb_iv_get(obj, "@name")
25/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 27. Rubyレベルのメソッド呼び出し
も可
rb_funcall(obj, rb_intern("methodname"), arg, ...);
26/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 28. raise & rescue
/* 例外を発生させる */
rb_raise(rb_eRuntimeError, "%s: %d", "abc", 123);
...
/* begin func1(arg1) rescue func2(arg2) end みたいな */
VALUE func1(VALUE arg1)
{
...
}
VALUE func2(VALUE arg2)
{
...
}
...
rb_rescue(func1, arg1, func2, arg2)
27/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 29. クラスの一部のメソッドをCで書
くこともできる
[Ruby]
class Hoge
def xxx()
...
end
end
[C]
cHoge = rb_const_get(rb_cObject, rb_intern("Hoge"));
rb_define_method(cHoge, "zzz", hoge_zzz, 0);
28/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 32. さらに知りたけ
ればソース
ruby-X.Y.Z/*.
{h,c} 31/33
はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
- 34. ご清聴あり
がとうござ
いました
はじめてのRuby拡張ライブラリ
33/33
Powered by Rabbit 0.6.4