Para crear una extension en ruby lo primero que hay que hacer, es crear el "extconf.rb", basicamente tiene que tener el siguiente contenido:
# extconf.rb
require 'mkmf'
dir_config("exttest")
create_makefile("exttest")
Posteriormente, hay que crear el archivo del codigo fuente en C de la extension, que minimamente tiene que haber uno, en este caso creamos uno de prueba, bastante resumido, el cual crea un modulo ruby y le define dos metodos, ambos implementados en C:
// exttest.c
#include "ruby.h"
static VALUE foo(VALUE self) {
printf("Foo invoqued\n");
return Qnil;
}
static VALUE sum(VALUE self, VALUE a, VALUE b) {
return INT2NUM( NUM2INT(a) + NUM2INT(b) );
}
void
Init_exttest()
{
VALUE rb_exttest = rb_define_module("Exttest"); // definir el modulo
rb_define_singleton_method(rb_exttest, // en que modulo
"foo", // nombre del metodo
foo, // puntero a la implementacion C del metodo
0 // cantidad de argumentos del metodo
);
rb_define_singleton_method(rb_exttest, // en que modulo
"sum", // nombre del metodo
sum, // puntero a la implementacion C del metodo
2 // cantidad de argumentos del metodo
);
}
Para generar el makefile (solo hay que hacer esto una vez), se ejecuta el script extconf.rb:
ruby extconf.rb
Para construir la extension, se debe lanzar el siguiente comando:
make
Eso genera, entre otros archivos intermedios, extconf.so, el cual contiene la extension misma compilada a codigo nativo de la plataforma donde estan corriendo todo, para instalarla en el sistema, hay que correr (como root):
make install
Para usar la extension:
# test.rb
require 'rubygems'
require 'exttest'
Exttest.foo # el metodo foo definido en exttest.c!!
print Exttest.sum(4,9),"\n" # el metodo sum definido en exttest.c!!
Posteriormente, se pueden hacer cosas mas interesantes como definir clases, clases anidadas en modulos, metodos, etc...
Para la proxima voy a explicar como encapsular la extension como gem y distribuirla
Para la proxima voy a explicar como encapsular la extension como gem y distribuirla
links:
* http://onlamp.com/pub/a/onlamp/2004/11/18/extending_ruby.html: Fuente que inspiro este articulo y ejemplo practico de como wrappear la libreria GenX como libreria ruby GenX4r
* http://rhg.rubyforge.org/chapter04.html: Tutorial que muestra como definir clases y modulos
* http://ruby-doc.org/doxygen/1.8.4/group__ruby__interp.html: Documentacion completa de funciones C para definir extensiones de ruby incluyendo funciones de conversion de datos
No hay comentarios:
Publicar un comentario