a funcao, o segundo e o ID do nome da funcao, o terceiro o numero de parametros e dai em diante os parametros. No caso acima nao era necessario passar parametros, assim, o terceiro argumento foi 0 e nao houve mais nenhum argumento apos este.A macro StringValuePtr retorna uma string (char *) com o valor da string em ruby. Apos tudo isto o interpretador e finalizado, chamando ruby_finalize.Os prototipos podem ser entendidos como:ID rb_intern(char *nome);VALUE rb_str_new2(char *string);VALUE rb_funcall(VALUE obj, ID nome_id, int argc, ...);char* StringValuePtr(VALUE string);O executavel pode ser gerado usando o GCC da seguinte maneira:hugo@hugo-laptop:~/Desktop/posts/rb$ gcc -o upcase upcase.c \> -I/usr/lib/ruby/1.8/i486-linux -lruby1.8hugo@hugo-laptop:~/Desktop/posts/rb$ ./upcaseantes: hugo, depois: HUGOhugo@hugo-laptop:~/Desktop/posts/rb$A opcao -lruby1.8 varia de sistema pra sistema, mas normalmente a opcao pra linkar a biblioteca do interpretador e -lruby ou -lrubyVERSAO.Algo correspondente em Ruby seria:hugo@hugo-laptop:~/Desktop/posts/rb$ irbirb(main):001:0> string_minuscula = "hugo"=> "hugo"irb(main):002:0> resultado = string_minuscula.upcase=> "HUGO"irb(main):003:0> puts "antes: #{string_minuscula}, " \irb(main):004:0* "depois: #{resultado}"antes: hugo, depois: HUGO=> nilirb(main):005:0>Exemplo #2 - estendendo o interpretador: Criando um modulo com funcoes matematicasNesse exemplo criaremos um modulo Matematica que contera duas funcoes: fatorial e raiz_quadrada.Em Ruby todo modulo de extensao precisa de apenas uma coisa: uma funcao Init_NOMEDOMODULO. O codigo segue:#include "ruby.h"#include <math.h>int fatorial_c_puro(int n){ if (n <= 1) return 1; return n * fatorial_c_puro(n-1);}VALUE raiz_quadrada(VALUE self, VALUE x){ double raiz = sqrt(NUM2DBL(x)); return rb_float_new(raiz);}VALUE fatorial(VALUE self, VALUE x){ int x_int = NUM2INT(x); return INT2NUM(fatorial_c_puro(x_int));}void Init_matematica(){ VALUE modulo_matematica; modulo_matematica = rb_define_module("Matematica"); rb_define_module_function(modulo_matematica, \ "fatorial", \ fatorial, \ 1); rb_define_module_function(modulo_matematica, \ "raiz_quadrada", \ raiz_quadrada, \ 1);}A abordagem foi identica a usada no post sobre a Python/C API, que consiste em ter 1 funcao em C puro pra calcular fatorial e duas que usam a API.A macro NUM2DBL converte um objeto numerico de ruby pro tipo double em C. A NUM2INT converte um objeto numerico pra um int e INT2NUM converte um int pra Fixnum ou Bignum.A funcao responsavel por iniciar o modulo sempre que e feito um require e Init_matematica. Reparem que em Python seria initmatematica, mas em Ruby o prefixo e Init_ ao inves de init.Dentro da funcao que inicializa o modulo temos uma variavel modulo_matematica que guarda o modulo em si. rb_define_module define um modulo com o valor de Matematica e duas funcoes fatorial e raiz_quadrada, ambas tem 1 parametro. Assim, a funcao fatorial sera acessivel da seguinte forma Matematica::fatorial.Os prototipos podem ser entendidos como:double NUM2DBL(VALUE n);int NUM2INT(VALUE n);VALUE INT2NUM(int n);VALUE rb_define_module(char *nome);void rb_define_module_function(VALUE modulo, \ char *nome, \ VALUE(*funcao)(), \ int argc);Agora precisamos gerar o modulo pra ser usado pelo interpretador Ruby. A maneira mais elegante de se fazer isso e usar o modulo padrao mkmf. Porem, as duas maneiras serao mostradas.A primeira maneira e atraves de uma chamada direta ao gcc, que e simples:hugo@hugo-laptop:~/Desktop/posts/rb$ gcc -shared matematica.c \> -I/usr/lib/ruby/1.8/i486-linux -o matematica.so -lmhugo@hugo-laptop:~/Desktop/posts/rb$A outra maneira e atraves do mkmf. Essa maneira consiste em criar um script em ruby que e responsavel por criar um Makefile que gera o modulo. O arquivo se chamara extconf.rb e o conteudo sera o seguinte:require 'mkmf'create_makefile('matematica')Isso significa que nos criaremos um Makefile que usara o compilador padrao, criando o arquivo matematica.so, matematica.dll ou matematica.bundle -