SlideShare a Scribd company logo
Ruby
             Ruby
             拡張モジュール⼊⾨
             拡張モジュール⼊⾨
             むらけん




2007-11-17
おしながき
             おしながき
   拡張モジュールとは
   なにもしない拡張モジュール
   hello.so
   拡張モジュールを作る前に
   まとめ



2007-11-17      Ruby 勉強会@札幌 #6   1
拡張モジュールとは
             拡張モジュールとは
               ⽇本語でおk


                                2



2007-11-17     Ruby 勉強会@札幌 #6
拡張モジュールって何?
             拡張モジュールって何?
拡張モジュールとは・・・
        Ruby では実現不可能だけど,C ⾔語なら実現可
        能な事柄を,C ⾔語で実装して Ruby から使えるよ
        うにするための共有ライブラリ
        Ruby で実装すると遅いけど,C ⾔語なら実⽤的な
        実⾏速度を実現できるようなアルゴリズムなどを,C
        ⾔語で実装して Ruby から使えるようにするための
        共有ライブラリ
             アセンブリ⾔語も使えるよ\(^o^)/
2007-11-17           Ruby 勉強会@札幌 #6   3
拡張モジュールの例
             拡張モジュールの例
   標準添付                            独⽴配布
        Ruby/OpenSSL                     Ruby/GNOME2
        Ruby/Win32API                    RubyCocoa
        Enumerator                       Libxml-Ruby
        iconv                            Ruby PostgreSQL
        Ruby/Tk                          MySQL/Ruby
        Win32OLE                         fastthread
        Ruby/Zlib                        http11 (mongrel)


2007-11-17              Ruby 勉強会@札幌 #6                      4
なにもしない
              なにもしない
             拡張モジュール
             拡張モジュール
             nothing to do


                                5



2007-11-17     Ruby 勉強会@札幌 #6
準   備
             準   備
 3つのファイルを nothing ディレクトリの中に⼊れましょう

 [nothing.c]                [extconf.rb]
 void                       require 'mkmf'
 Init_nothing(void)
 {                          create_makefile('nothing')
 }
                            ~/nothing$ ls
 [depends]                  depends extconf.rb nothing.c
 nothing.o: nothing.c       ~/nothing$

2007-11-17              Ruby 勉強会@札幌 #6                     6
コンパイル
             コンパイル
 extconf.rb を実⾏することによって Makefile が作られます.
 作成された Makefile を make することでコンパイルします.
 make の後に⽣成される nothing.so が拡張モジュールです.

 ~/nothing$ ruby extconf.rb
 creating Makefile
 ~/nothing$ ls
 Makefile depends extconf.rb                nothing.c
 ~/nothing$ make
 cc -I. -I/usr/lib/ruby/1.8/i486-linux -I/usr/lib/ruby/1.8/i486-linux -I. -fPIC -fno-stric...
 cc -shared -o nothing.so nothing.o -Lquot;.quot; -Lquot;/usr/libquot; -L. -rdynamic -Wl,-export-dynamic ...
 ~/nothing$ ls
 Makefile depends          extconf.rb       nothing.c nothing.o            nothing.so

2007-11-17                          Ruby 勉強会@札幌 #6                                              7
使ってみる
             使ってみる
 出来上がった nothing.so を Ruby から使うには
 require 'nothing' を⾏います.

 ~/nothing$ irb
 irb(main):001:0> require 'nothing'
 => true
 irb(main):002:0> exit
 ~/nothing$




2007-11-17                Ruby 勉強会@札幌 #6   8
ここまでのまとめ (1)
             ここまでのまとめ (1)
   拡張モジュールに必ず必要な関数
        void Init_モジュール名(void) { ... }
        拡張モジュールがロードされた直後に Ruby インタ
        プリタがこの関数を呼び出す
         本来ならば,この関数の中で拡張モジュールの初
        期化処理が⾏われる




2007-11-17        Ruby 勉強会@札幌 #6         9
ここまでのまとめ (2)
              ここまでのまとめ (2)
   Ruby に標準添付されている拡張モジュール
   開発環境
        extconf.rb の中で mkmf ライブラリを⽤いて,
        Makefile を作成するための処理を⾏う
             • とりあえず
                  create_makefile('モジュール名')
               と書くことで「モジュール名.so」を⽣成するための
               Makefile が作られる
        depends ファイルの中に Makefile に書いて欲し
        い依存関係を記述する
2007-11-17              Ruby 勉強会@札幌 #6        10
hello.so
             hello.so
             そう,こんにちわ


                               11



2007-11-17    Ruby 勉強会@札幌 #6
hello.c
              hello.c
 [hello.c]                                 [左から続き]
 #include <ruby.h>                         void
 #include <stdio.h>                        Init_hello(void)
                                           {
 static VALUE                                VALUE cHello;
 hello_hello(VALUE self)
 {                                             printf(quot;[XXX] Init_hello¥nquot;);
   VALUE str;
                                               cHello = rb_define_class(
     printf(quot;[XXX] hello_hello¥nquot;);                       quot;Helloquot;, rb_cObject);
                                               rb_define_method(
     str = rb_str_new2(quot;hello, worldquot;);          cHello, quot;helloquot;, hello_hello, 0);
     rb_io_puts(1, &str, rb_stdout);       }

     return self;
 }


2007-11-17                        Ruby 勉強会@札幌 #6                                     12
コンパイル
             コンパイル
 [extconf.rb]                            ~/hello$   ls
 require 'mkmf'                          depends    extconf.rb hello.c
                                         ~/hello$   ruby extconf.rb
 create_makefile('hello')                creating   Makefile
                                         ~/hello$   make
                                         cc -I. -I/usr/lib/ruby/1.8/i486-linux -
                                         I/usr/lib/ruby/1.8/i486-linux -I. -fPIC -
                                         fno-strict-aliasing -g -O2 -fPIC -c
 [depends]
                                         hello.c
 hello.o: hello.c $(hdrdir)/ruby.h
                                         cc -shared -o hello.so hello.o -Lquot;.quot; -
                                         Lquot;/usr/libquot; -L. -rdynamic -Wl,-export-
                                         dynamic    -lruby1.8 -lpthread -ldl -
                                         lcrypt -lm   -lc
                                         ~/hello$ ls
                                         depends extconf.rb hello.c hello.o
                                         hello.so



2007-11-17                      Ruby 勉強会@札幌 #6                                       13
使ってみる
             使ってみる
 ~/hello$ irb                            void
 irb(main):001:0> require 'hello'        Init_hello(void)
 [XXX] Init_hello                        {
 => true                                   VALUE cHello;
 irb(main):002:0> h = Hello.new
 => #<Hello:0xb7c7e590>                    printf(quot;[XXX] Init_hello¥nquot;);
 irb(main):003:0> h.hello                ======================================
 [XXX] hello_hello                       static VALUE
 hello, world                            hello_hello(VALUE self)
 => #<Hello:0xb7c7e590>                  {
 irb(main):004:0> exit                     VALUE str;
 ~/hello$
                                           printf(quot;[XXX] hello_hello¥nquot;);
                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                           return self;
                                         }


2007-11-17                      Ruby 勉強会@札幌 #6                                14
ここまでのまとめ (1)
             ここまでのまとめ (1)
   クラスを定義する
        rb_define_class(クラス名, 親クラスオブジェクト)
   クラスにインスタンスメソッドを定義する
        rb_define_method(
             クラスオブジェクト,
             メソッド名,
             メソッドを実装している関数,
             引数の個数)

2007-11-17         Ruby 勉強会@札幌 #6       15
ここまでのまとめ (2)
               ここまでのまとめ (2)
   メソッドの実体となる関数 (hello_hello)
        第1仮引数・・・レシーバオブジェクト
        その他・・・メソッドの引数

   Ruby の⽂字列オブジェクトを⽣成する
        rb_str_new2(C の⽂字列)

   puts
        rb_io_puts(1, &⽂字列, rb_stdout)
             • 本当は rb_io_puts(argc, argv, rb_stdout) で,argv が puts
               に渡す実引数の C 配列,argc がその⻑さ

2007-11-17                    Ruby 勉強会@札幌 #6                         16
拡張モジュールを
             拡張モジュールを
               作る前に
               作る前に
             そんなに難しくないよ


                                17



2007-11-17     Ruby 勉強会@札幌 #6
おちついて⼀読すべし
             おちついて⼀読すべし
   Ruby には拡張モジュールの作り⽅のドキュメ
   ントがもれなくついてくる!
        README.EXT
        README.EXT.ja




2007-11-17          Ruby 勉強会@札幌 #6   18
拡張モジュールを作るとは
             拡張モジュールを作るとは
             どういうことか?
             どういうことか?

     Ruby インタプリタが理解できることば
        構⽂⽊
        C ⾔語


   拡張モジュールを作る
       = Ruby インタプリタとお喋りする


2007-11-17       Ruby 勉強会@札幌 #6   19
参考になるものたち
             参考になるものたち
     Ruby のソースを読むべし!
        array.c
        hash.c
        object.c
        string.c

   よく使うクラスを実装しているコードを読むことで
   拡張モジュール作成のための知識を増やそう

2007-11-17         Ruby 勉強会@札幌 #6   20
まとめ
              まとめ
             MA☆TO☆めけーも


                                21



2007-11-17     Ruby 勉強会@札幌 #6
拡張モジュールを作ろう!

             C ⾔語で Ruby とお喋りしよう




2007-11-17         Ruby 勉強会@札幌 #6   22

More Related Content

Ruby 拡張モジュール入門

  • 1. Ruby Ruby 拡張モジュール⼊⾨ 拡張モジュール⼊⾨ むらけん 2007-11-17
  • 2. おしながき おしながき 拡張モジュールとは なにもしない拡張モジュール hello.so 拡張モジュールを作る前に まとめ 2007-11-17 Ruby 勉強会@札幌 #6 1
  • 3. 拡張モジュールとは 拡張モジュールとは ⽇本語でおk 2 2007-11-17 Ruby 勉強会@札幌 #6
  • 4. 拡張モジュールって何? 拡張モジュールって何? 拡張モジュールとは・・・ Ruby では実現不可能だけど,C ⾔語なら実現可 能な事柄を,C ⾔語で実装して Ruby から使えるよ うにするための共有ライブラリ Ruby で実装すると遅いけど,C ⾔語なら実⽤的な 実⾏速度を実現できるようなアルゴリズムなどを,C ⾔語で実装して Ruby から使えるようにするための 共有ライブラリ アセンブリ⾔語も使えるよ\(^o^)/ 2007-11-17 Ruby 勉強会@札幌 #6 3
  • 5. 拡張モジュールの例 拡張モジュールの例 標準添付 独⽴配布 Ruby/OpenSSL Ruby/GNOME2 Ruby/Win32API RubyCocoa Enumerator Libxml-Ruby iconv Ruby PostgreSQL Ruby/Tk MySQL/Ruby Win32OLE fastthread Ruby/Zlib http11 (mongrel) 2007-11-17 Ruby 勉強会@札幌 #6 4
  • 6. なにもしない なにもしない 拡張モジュール 拡張モジュール nothing to do 5 2007-11-17 Ruby 勉強会@札幌 #6
  • 7. 備 準 備 3つのファイルを nothing ディレクトリの中に⼊れましょう [nothing.c] [extconf.rb] void require 'mkmf' Init_nothing(void) { create_makefile('nothing') } ~/nothing$ ls [depends] depends extconf.rb nothing.c nothing.o: nothing.c ~/nothing$ 2007-11-17 Ruby 勉強会@札幌 #6 6
  • 8. コンパイル コンパイル extconf.rb を実⾏することによって Makefile が作られます. 作成された Makefile を make することでコンパイルします. make の後に⽣成される nothing.so が拡張モジュールです. ~/nothing$ ruby extconf.rb creating Makefile ~/nothing$ ls Makefile depends extconf.rb nothing.c ~/nothing$ make cc -I. -I/usr/lib/ruby/1.8/i486-linux -I/usr/lib/ruby/1.8/i486-linux -I. -fPIC -fno-stric... cc -shared -o nothing.so nothing.o -Lquot;.quot; -Lquot;/usr/libquot; -L. -rdynamic -Wl,-export-dynamic ... ~/nothing$ ls Makefile depends extconf.rb nothing.c nothing.o nothing.so 2007-11-17 Ruby 勉強会@札幌 #6 7
  • 9. 使ってみる 使ってみる 出来上がった nothing.so を Ruby から使うには require 'nothing' を⾏います. ~/nothing$ irb irb(main):001:0> require 'nothing' => true irb(main):002:0> exit ~/nothing$ 2007-11-17 Ruby 勉強会@札幌 #6 8
  • 10. ここまでのまとめ (1) ここまでのまとめ (1) 拡張モジュールに必ず必要な関数 void Init_モジュール名(void) { ... } 拡張モジュールがロードされた直後に Ruby インタ プリタがこの関数を呼び出す 本来ならば,この関数の中で拡張モジュールの初 期化処理が⾏われる 2007-11-17 Ruby 勉強会@札幌 #6 9
  • 11. ここまでのまとめ (2) ここまでのまとめ (2) Ruby に標準添付されている拡張モジュール 開発環境 extconf.rb の中で mkmf ライブラリを⽤いて, Makefile を作成するための処理を⾏う • とりあえず create_makefile('モジュール名') と書くことで「モジュール名.so」を⽣成するための Makefile が作られる depends ファイルの中に Makefile に書いて欲し い依存関係を記述する 2007-11-17 Ruby 勉強会@札幌 #6 10
  • 12. hello.so hello.so そう,こんにちわ 11 2007-11-17 Ruby 勉強会@札幌 #6
  • 13. hello.c hello.c [hello.c] [左から続き] #include <ruby.h> void #include <stdio.h> Init_hello(void) { static VALUE VALUE cHello; hello_hello(VALUE self) { printf(quot;[XXX] Init_hello¥nquot;); VALUE str; cHello = rb_define_class( printf(quot;[XXX] hello_hello¥nquot;); quot;Helloquot;, rb_cObject); rb_define_method( str = rb_str_new2(quot;hello, worldquot;); cHello, quot;helloquot;, hello_hello, 0); rb_io_puts(1, &str, rb_stdout); } return self; } 2007-11-17 Ruby 勉強会@札幌 #6 12
  • 14. コンパイル コンパイル [extconf.rb] ~/hello$ ls require 'mkmf' depends extconf.rb hello.c ~/hello$ ruby extconf.rb create_makefile('hello') creating Makefile ~/hello$ make cc -I. -I/usr/lib/ruby/1.8/i486-linux - I/usr/lib/ruby/1.8/i486-linux -I. -fPIC - fno-strict-aliasing -g -O2 -fPIC -c [depends] hello.c hello.o: hello.c $(hdrdir)/ruby.h cc -shared -o hello.so hello.o -Lquot;.quot; - Lquot;/usr/libquot; -L. -rdynamic -Wl,-export- dynamic -lruby1.8 -lpthread -ldl - lcrypt -lm -lc ~/hello$ ls depends extconf.rb hello.c hello.o hello.so 2007-11-17 Ruby 勉強会@札幌 #6 13
  • 15. 使ってみる 使ってみる ~/hello$ irb void irb(main):001:0> require 'hello' Init_hello(void) [XXX] Init_hello { => true VALUE cHello; irb(main):002:0> h = Hello.new => #<Hello:0xb7c7e590> printf(quot;[XXX] Init_hello¥nquot;); irb(main):003:0> h.hello ====================================== [XXX] hello_hello static VALUE hello, world hello_hello(VALUE self) => #<Hello:0xb7c7e590> { irb(main):004:0> exit VALUE str; ~/hello$ printf(quot;[XXX] hello_hello¥nquot;); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return self; } 2007-11-17 Ruby 勉強会@札幌 #6 14
  • 16. ここまでのまとめ (1) ここまでのまとめ (1) クラスを定義する rb_define_class(クラス名, 親クラスオブジェクト) クラスにインスタンスメソッドを定義する rb_define_method( クラスオブジェクト, メソッド名, メソッドを実装している関数, 引数の個数) 2007-11-17 Ruby 勉強会@札幌 #6 15
  • 17. ここまでのまとめ (2) ここまでのまとめ (2) メソッドの実体となる関数 (hello_hello) 第1仮引数・・・レシーバオブジェクト その他・・・メソッドの引数 Ruby の⽂字列オブジェクトを⽣成する rb_str_new2(C の⽂字列) puts rb_io_puts(1, &⽂字列, rb_stdout) • 本当は rb_io_puts(argc, argv, rb_stdout) で,argv が puts に渡す実引数の C 配列,argc がその⻑さ 2007-11-17 Ruby 勉強会@札幌 #6 16
  • 18. 拡張モジュールを 拡張モジュールを 作る前に 作る前に そんなに難しくないよ 17 2007-11-17 Ruby 勉強会@札幌 #6
  • 19. おちついて⼀読すべし おちついて⼀読すべし Ruby には拡張モジュールの作り⽅のドキュメ ントがもれなくついてくる! README.EXT README.EXT.ja 2007-11-17 Ruby 勉強会@札幌 #6 18
  • 20. 拡張モジュールを作るとは 拡張モジュールを作るとは どういうことか? どういうことか? Ruby インタプリタが理解できることば 構⽂⽊ C ⾔語 拡張モジュールを作る = Ruby インタプリタとお喋りする 2007-11-17 Ruby 勉強会@札幌 #6 19
  • 21. 参考になるものたち 参考になるものたち Ruby のソースを読むべし! array.c hash.c object.c string.c よく使うクラスを実装しているコードを読むことで 拡張モジュール作成のための知識を増やそう 2007-11-17 Ruby 勉強会@札幌 #6 20
  • 22. まとめ まとめ MA☆TO☆めけーも 21 2007-11-17 Ruby 勉強会@札幌 #6
  • 23. 拡張モジュールを作ろう! C ⾔語で Ruby とお喋りしよう 2007-11-17 Ruby 勉強会@札幌 #6 22