Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Extending Ruby with C

Extending Ruby with C

A Learning Lunch presentation about writing C extensions for Ruby.

Paul Mucur

May 08, 2012
Tweet

More Decks by Paul Mucur

Other Decks in Programming

Transcript

  1. static  VALUE rb_ary_push_1(VALUE  ary,  VALUE  item) {      

     long  idx  =  RARRAY_LEN(ary);        if  (idx  >=  ARY_CAPA(ary))  {                ary_double_capa(ary,  idx);        }        RARRAY_PTR(ary)[idx]  =  item;        ARY_SET_LEN(ary,  idx  +  1);        return  ary; }
  2. require  "world" describe  World  do    describe  "#hello"  do  

         it  "greets  the  world"  do            World.hello.should  ==  "Hello,  World!"        end    end end
  3. #include  <ruby.h> static  VALUE  world_hello(VALUE  obj)  {    return  rb_str_new("Hello,

     World!",  13); } void  Init_world(void)  {    VALUE  world_mWorld  =  rb_define_module("World");    rb_define_module_function(world_mWorld,  "hello",            world_hello,  0); }
  4. “If argc is -1, the function will be called as:

    VALUE func(int argc, VALUE *argv, VALUE obj) where argc is the actual number of arguments, argv is the C array of the arguments, and obj is the receiver.”
  5. def  hello(name  =  nil)    if  name      

     "Hello,  #{name}!"    else        "Hello,  World!"    end end
  6. static  VALUE  world_hello(int  argc,  VALUE  *argv,  VALUE  obj)  {  

     VALUE  name;    rb_scan_args(argc,  argv,  "01",  &name);        ... }
  7. static  VALUE  world_hello(int  argc,  VALUE  *argv,  VALUE  obj)  {  

     VALUE  name;    rb_scan_args(argc,  argv,  "01",  &name);    if  (NIL_P(name))  {        return  rb_str_new("Hello,  World!",  13);    }  else  {        ...    } }
  8. static  VALUE  world_hello(int  argc,  VALUE  *argv,  VALUE  obj)  {  

     VALUE  name,  greeting;    rb_scan_args(argc,  argv,  "01",  &name);    if  (NIL_P(name))  {        greeting  =  rb_str_new("Hello,  World!",  13);    }  else  {        greeting  =  rb_str_new("Hello,  ",  7);        rb_str_cat(greeting,  RSTRING_PTR(name),  RSTRING_LEN(name));        rb_str_cat(greeting,  "!",  1);    }    return  greeting; }
  9. $  rake  clean  test rm  -­‐r  tmp/x86_64-­‐darwin11.3.0/world/1.9.3 mkdir  -­‐p  tmp/x86_64-­‐darwin11.3.0/world/1.9.3

    cd  tmp/x86_64-­‐darwin11.3.0/world/1.9.3 /Users/mudge/.rbenv/versions/1.9.3-­‐p125/bin/ruby  -­‐ I.  ../../../../ext/world/extconf.rb creating  Makefile cd  -­‐ cd  tmp/x86_64-­‐darwin11.3.0/world/1.9.3 make compiling  ../../../../ext/world/world.c linking  shared-­‐object  world.bundle cd  -­‐ install  -­‐c  tmp/x86_64-­‐darwin11.3.0/world/1.9.3/world.bundle  lib/ world.bundle /Users/mudge/.rbenv/versions/1.9.3-­‐p125/bin/ruby  -­‐S  rspec  ./ spec/world_spec.rb .. Finished  in  0.00081  seconds 2  examples,  0  failures