SlideShare a Scribd company logo
1 of 34
Download to read offline
はじめてのRuby拡
         張ライブラリ
                   とみたまさひろ
                     2010-05-22

はじめてのRuby拡張ライブラリ         Powered by Rabbit 0.6.4
自己紹介
    ✓ とみた まさひろ
    ✓ プログラマー
    ✓ mailto:tommy@tmtm.org
    ✓ http://d.hatena.ne.jp/tmtms
    ✓ http://twitter.com/tmtms
                                            1/33
はじめてのRuby拡張ライブラリ                 Powered by Rabbit 0.6.4
自己紹介

    ✓ 日本Rubyの会
    ✓ 日本MySQLユーザ会
    ✓ Ruby/MySQL ライブラリ
    ✓ Ruby歴, MySQL歴 十数年

                                     2/33
はじめてのRuby拡張ライブラリ          Powered by Rabbit 0.6.4
自己紹介




                   こんな本書きました

                                          3/33
はじめてのRuby拡張ライブラリ               Powered by Rabbit 0.6.4
NSEG #1 で




                                          4/33
はじめてのRuby拡張ライブラリ               Powered by Rabbit 0.6.4
Ruby拡張
  ライブラリ
                              5/33
はじめてのRuby拡張ライブラリ   Powered by Rabbit 0.6.4
Ruby
   は遅い
はじめてのRuby拡張ライブラリ
                              6/33
                   Powered by Rabbit 0.6.4
こんなに遅い




                                       7/33
はじめてのRuby拡張ライブラリ            Powered by Rabbit 0.6.4
Rubyが遅いの
  ならCで書けば
   いいじゃない
                              8/33
はじめてのRuby拡張ライブラリ   Powered by Rabbit 0.6.4
Cのライブラ
  リをRubyか
  ら使いたい                       9/33
はじめてのRuby拡張ライブラリ   Powered by Rabbit 0.6.4
ということ
   で拡張ライ
    ブラリ
はじめてのRuby拡張ライブラリ
                           10/33
                   Powered by Rabbit 0.6.4
通常のライブラリ

    ✓ Ruby で書かれている
    ✓ 拡張子 .rb
    ✓ require 'hoge'
    ✓ require 'hoge.rb'

                                      11/33
はじめてのRuby拡張ライブラリ              Powered by Rabbit 0.6.4
拡張ライブラリ
    ✓ C で書かれている
    ✓ 拡張子 .so (Linux の場合)
    ✓ require 'hoge' (.rb が優先)
    ✓ require 'hoge.o'
    ✓ require 'hoge.so'
                                         12/33
はじめてのRuby拡張ライブラリ                 Powered by Rabbit 0.6.4
作り方
                           13/33
はじめてのRuby拡張ライブラリ   Powered by Rabbit 0.6.4
専用ディレクトリが必要


                   $ ls hoge/
                   extconf.rb
                   hoge.c


                                        14/33
はじめてのRuby拡張ライブラリ                Powered by Rabbit 0.6.4
hoge.c

   拡張ライブラリ本体
        /* require 'hoge' 時に呼ばれる関数 */
        void Init_hoge(void)
        {
          puts("Hello");
        }


                                          15/33
はじめてのRuby拡張ライブラリ                  Powered by Rabbit 0.6.4
extconf.rb

   拡張ライブラリを作るための
   Makefile を作る

              require 'mkmf'
              create_makefile 'hoge'

                                               16/33
はじめてのRuby拡張ライブラリ                       Powered by Rabbit 0.6.4
コンパイル&実行
             $ 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
クラス&メソッド
              #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
メソッド引数

       /* 引数なし */
       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
不定個引数
               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
データ変換
   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
データ変換

   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
真偽値


                   Ruby             C
     true                  Qtrue
     false                 Qfalse
     nil                   Qnil

                                                23/33
はじめてのRuby拡張ライブラリ                        Powered by Rabbit 0.6.4
定義済みクラス

           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
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
Rubyレベルのメソッド呼び出し
         も可



        rb_funcall(obj, rb_intern("methodname"), arg, ...);




                                                              26/33
はじめてのRuby拡張ライブラリ                                      Powered by Rabbit 0.6.4
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
クラスの一部のメソッドを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
その他
  もろもろ
はじめてのRuby拡張ライブラリ
                           29/33
                   Powered by Rabbit 0.6.4
詳しくは
 README.EXT.ja
                           30/33
はじめてのRuby拡張ライブラリ   Powered by Rabbit 0.6.4
さらに知りたけ
    ればソース
  ruby-X.Y.Z/*.
      {h,c}                31/33
はじめてのRuby拡張ライブラリ   Powered by Rabbit 0.6.4
サンプルも多
 数あるよ ruby-
  X.Y.Z/ext/*
                           32/33
はじめてのRuby拡張ライブラリ   Powered by Rabbit 0.6.4
ご清聴あり
  がとうござ
   いました
はじめてのRuby拡張ライブラリ
                           33/33
                   Powered by Rabbit 0.6.4

More Related Content

What's hot

JVM-Reading-ConcurrentMarkSweep
JVM-Reading-ConcurrentMarkSweepJVM-Reading-ConcurrentMarkSweep
JVM-Reading-ConcurrentMarkSweepMinoru Nakamura
 
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15Mitsuru Kariya
 
Perlと出会い、Perlを作る
Perlと出会い、Perlを作るPerlと出会い、Perlを作る
Perlと出会い、Perlを作るgoccy
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめSatoshi imai
 
constexpr idioms
constexpr idiomsconstexpr idioms
constexpr idiomsfimbul
 
ROS Tutorial 02 - CIT
ROS Tutorial 02 - CITROS Tutorial 02 - CIT
ROS Tutorial 02 - CITDaiki Maekawa
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarrayRyosuke839
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目龍一 田中
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するshigeki_ohtsu
 
Node-v0.12の新機能について
Node-v0.12の新機能についてNode-v0.12の新機能について
Node-v0.12の新機能についてshigeki_ohtsu
 
高度に最適化された移植可能なメモリマネージャ
高度に最適化された移植可能なメモリマネージャ高度に最適化された移植可能なメモリマネージャ
高度に最適化された移植可能なメモリマネージャDADA246
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングKohsuke Yuasa
 
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16Mitsuru Kariya
 
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Ransui Iso
 
ROS JAPAN Users Group Meetup 01
ROS JAPAN Users Group Meetup 01ROS JAPAN Users Group Meetup 01
ROS JAPAN Users Group Meetup 01Daiki Maekawa
 

What's hot (20)

JVM-Reading-ConcurrentMarkSweep
JVM-Reading-ConcurrentMarkSweepJVM-Reading-ConcurrentMarkSweep
JVM-Reading-ConcurrentMarkSweep
 
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15
 
Perlと出会い、Perlを作る
Perlと出会い、Perlを作るPerlと出会い、Perlを作る
Perlと出会い、Perlを作る
 
Rubyの黒魔術
Rubyの黒魔術Rubyの黒魔術
Rubyの黒魔術
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
 
constexpr idioms
constexpr idiomsconstexpr idioms
constexpr idioms
 
Boost tour 1_40_0
Boost tour 1_40_0Boost tour 1_40_0
Boost tour 1_40_0
 
Boost Tour 1_58_0 merge
Boost Tour 1_58_0 mergeBoost Tour 1_58_0 merge
Boost Tour 1_58_0 merge
 
ROS Tutorial 02 - CIT
ROS Tutorial 02 - CITROS Tutorial 02 - CIT
ROS Tutorial 02 - CIT
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
 
Node-v0.12の新機能について
Node-v0.12の新機能についてNode-v0.12の新機能について
Node-v0.12の新機能について
 
Altanative macro
Altanative macroAltanative macro
Altanative macro
 
高度に最適化された移植可能なメモリマネージャ
高度に最適化された移植可能なメモリマネージャ高度に最適化された移植可能なメモリマネージャ
高度に最適化された移植可能なメモリマネージャ
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
 
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4
 
Stream2の基本
Stream2の基本Stream2の基本
Stream2の基本
 
ROS JAPAN Users Group Meetup 01
ROS JAPAN Users Group Meetup 01ROS JAPAN Users Group Meetup 01
ROS JAPAN Users Group Meetup 01
 

Similar to はじめてのRuby拡張ライブラリ

Ruby&Active Support for expert 3
Ruby&Active Support for expert 3Ruby&Active Support for expert 3
Ruby&Active Support for expert 3xibbar
 
メタメタプログラミングRuby
メタメタプログラミングRubyメタメタプログラミングRuby
メタメタプログラミングRubyemasaka
 
Rubinius Under a Microscope
Rubinius Under a MicroscopeRubinius Under a Microscope
Rubinius Under a Microscope高広 内山
 
Ruby Extended Library
Ruby Extended LibraryRuby Extended Library
Ruby Extended LibraryAkio Tajima
 
Rubyにメソッドを追加して遊ぶ話
Rubyにメソッドを追加して遊ぶ話Rubyにメソッドを追加して遊ぶ話
Rubyにメソッドを追加して遊ぶ話Masaya Konishi
 
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)inaz2
 
Ruby in Wheezy @ 関西闇Ruby
Ruby in Wheezy @ 関西闇RubyRuby in Wheezy @ 関西闇Ruby
Ruby in Wheezy @ 関西闇RubyYouhei SASAKI
 
Rails基礎講座 part.1
Rails基礎講座 part.1Rails基礎講座 part.1
Rails基礎講座 part.1Jun Yokoyama
 
ffi for rubyists
ffi for rubyistsffi for rubyists
ffi for rubyistsnanki
 
とっとるびー(2回目)発表資料
とっとるびー(2回目)発表資料とっとるびー(2回目)発表資料
とっとるびー(2回目)発表資料ionis111
 
Rails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd editionRails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd editionGoh Matsumoto
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogrammingMasanori Kado
 
PHPer のための Ruby 教室
PHPer のための Ruby 教室PHPer のための Ruby 教室
PHPer のための Ruby 教室higaki
 
名古屋Ruby会議02 LT:Ruby中級への道
名古屋Ruby会議02 LT:Ruby中級への道名古屋Ruby会議02 LT:Ruby中級への道
名古屋Ruby会議02 LT:Ruby中級への道Shigeru UCHIYAMA
 
第1部「一時間で覚えるruby」
第1部「一時間で覚えるruby」第1部「一時間で覚えるruby」
第1部「一時間で覚えるruby」Hiromu Shioya
 

Similar to はじめてのRuby拡張ライブラリ (20)

Ruby紹介
Ruby紹介Ruby紹介
Ruby紹介
 
Ruby&Active Support for expert 3
Ruby&Active Support for expert 3Ruby&Active Support for expert 3
Ruby&Active Support for expert 3
 
メタメタプログラミングRuby
メタメタプログラミングRubyメタメタプログラミングRuby
メタメタプログラミングRuby
 
Rubinius Under a Microscope
Rubinius Under a MicroscopeRubinius Under a Microscope
Rubinius Under a Microscope
 
Ruby Extended Library
Ruby Extended LibraryRuby Extended Library
Ruby Extended Library
 
Rubyにメソッドを追加して遊ぶ話
Rubyにメソッドを追加して遊ぶ話Rubyにメソッドを追加して遊ぶ話
Rubyにメソッドを追加して遊ぶ話
 
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
 
Ruby in Wheezy @ 関西闇Ruby
Ruby in Wheezy @ 関西闇RubyRuby in Wheezy @ 関西闇Ruby
Ruby in Wheezy @ 関西闇Ruby
 
Rails基礎講座 part.1
Rails基礎講座 part.1Rails基礎講座 part.1
Rails基礎講座 part.1
 
ffi for rubyists
ffi for rubyistsffi for rubyists
ffi for rubyists
 
Ruby In Wheezy
Ruby In WheezyRuby In Wheezy
Ruby In Wheezy
 
とっとるびー(2回目)発表資料
とっとるびー(2回目)発表資料とっとるびー(2回目)発表資料
とっとるびー(2回目)発表資料
 
Rails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd editionRails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd edition
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
 
named_scope more detail
named_scope more detailnamed_scope more detail
named_scope more detail
 
PHPer のための Ruby 教室
PHPer のための Ruby 教室PHPer のための Ruby 教室
PHPer のための Ruby 教室
 
現実世界のJRuby
現実世界のJRuby現実世界のJRuby
現実世界のJRuby
 
名古屋Ruby会議02 LT:Ruby中級への道
名古屋Ruby会議02 LT:Ruby中級への道名古屋Ruby会議02 LT:Ruby中級への道
名古屋Ruby会議02 LT:Ruby中級への道
 
Packagist
PackagistPackagist
Packagist
 
第1部「一時間で覚えるruby」
第1部「一時間で覚えるruby」第1部「一時間で覚えるruby」
第1部「一時間で覚えるruby」
 

More from Masahiro Tomita

More from Masahiro Tomita (20)

お前の罪を数えろ
お前の罪を数えろお前の罪を数えろ
お前の罪を数えろ
 
Ruby 2.5
Ruby 2.5Ruby 2.5
Ruby 2.5
 
本当はこわいMySQLプロトコル
本当はこわいMySQLプロトコル本当はこわいMySQLプロトコル
本当はこわいMySQLプロトコル
 
ネットワークこわい
ネットワークこわいネットワークこわい
ネットワークこわい
 
CSV
CSVCSV
CSV
 
MySQLの文字コード事情 2017春版
MySQLの文字コード事情 2017春版MySQLの文字コード事情 2017春版
MySQLの文字コード事情 2017春版
 
MySQLの文字コード事情 2017版
MySQLの文字コード事情 2017版MySQLの文字コード事情 2017版
MySQLの文字コード事情 2017版
 
Ruby24
Ruby24Ruby24
Ruby24
 
MySQLの文字コード事情
MySQLの文字コード事情MySQLの文字コード事情
MySQLの文字コード事情
 
進捗と品質
進捗と品質進捗と品質
進捗と品質
 
MySQLを拡張する
MySQLを拡張するMySQLを拡張する
MySQLを拡張する
 
「理論から学ぶデータベース実践入門」読書会スペシャル
「理論から学ぶデータベース実践入門」読書会スペシャル「理論から学ぶデータベース実践入門」読書会スペシャル
「理論から学ぶデータベース実践入門」読書会スペシャル
 
MyNAができるまで
MyNAができるまでMyNAができるまで
MyNAができるまで
 
文字化け
文字化け文字化け
文字化け
 
Crystal
CrystalCrystal
Crystal
 
メールの暗号化
メールの暗号化メールの暗号化
メールの暗号化
 
文字化け
文字化け文字化け
文字化け
 
進捗と品質
進捗と品質進捗と品質
進捗と品質
 
アジャイルジャパン長野サテライト
アジャイルジャパン長野サテライトアジャイルジャパン長野サテライト
アジャイルジャパン長野サテライト
 
🍣=🍺
🍣=🍺🍣=🍺
🍣=🍺
 

はじめての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
  • 9. Rubyが遅いの ならCで書けば いいじゃない 8/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
  • 31. 詳しくは README.EXT.ja 30/33 はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
  • 32. さらに知りたけ ればソース ruby-X.Y.Z/*. {h,c} 31/33 はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
  • 33. サンプルも多 数あるよ ruby- X.Y.Z/ext/* 32/33 はじめてのRuby拡張ライブラリ Powered by Rabbit 0.6.4
  • 34. ご清聴あり がとうござ いました はじめてのRuby拡張ライブラリ 33/33 Powered by Rabbit 0.6.4