เขียน C extension เรียก Ruby จาก C เหมาะสำหรับ optimize เมธอดสำคัญด้วยความเร็ว C หรือ interface กับ C library (ทางเลือกอื่น: FFI module)
Your First C Extension
สร้าง extconf.rb:
require 'mkmf' create_header create_makefile 'foobar'
รัน ruby extconf.rb ได้ Makefile, extconf.h สร้าง foobar.c:
#include "ruby.h"
#include "extconf.h"
void Init_foobar() {
// C code here
}
Compile: make ได้ .so file ใช้ require โหลด
Writing A Ruby Method From C
C functions คืนค่า VALUE (Ruby object):
VALUE rb_return_nil() { return Qnil; }
Attach กับ module/class:
void Init_foobar() {
VALUE mod = rb_define_module("RubyGuides");
rb_define_method(mod, "return_nil", rb_return_nil, 0);
}
rb_define_method arguments: module, Ruby method name, C function name, argument count (0 = ไม่มีอาร์กิวเมนต์, -1 = variable)
Creating a Ruby Hash From C
ใช้ C API สร้าง/จัดการ Ruby objects:
VALUE create_hash() {
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("test"), INT2FIX(1));
return hash;
}
rb_str_new2 สร้าง Ruby string, INT2FIX แปลง integer → Ruby integer
Working With Strings
C functions รับพารามิเตอร์:
VALUE rb_print_length(VALUE self, VALUE str) {
if (RB_TYPE_P(str, T_STRING) == 1) {
return rb_sprintf("String length: %ld", RSTRING_LEN(str));
}
return Qnil;
}
void Init_foobar() {
rb_define_global_function("print_length", rb_print_length, 1);
}
RB_TYPE_P เช็ค type, RSTRING_LEN ความยาว string, RSTRING_PTR pointer ไปข้อมูล string
Define บน String class เอง: rb_define_method(rb_cString, "print_length", rb_print_length, 0);
Summary
เรียนรู้สร้าง C extension เรียก C จาก Ruby expose C functions, ทำงานกับ Ruby objects (strings, hashes) ต้อง recompile ทุกครั้งที่แก้ไข