
Ruby é uma linguagem incrível e traz uma produtividade excelente, mas em alguns tipos de software que você for escrever com ele talvez surja a necessidade de otimizar a velocidade de alguns trechos (assim como em qualquer linguagem de alto nível).
Você pode fazer isso codando esses trechos em C ou C++ (ou usando bibliotecas prontas destas linguagens) e depois chamando estes códigos através do Ruby de uma forma bem fácil e transparante.
O Objetivo deste artigo é te mostrar exatamente como fazer isto sem dor de cabeça, então siga o passo a passo e aumente seus skills de Programador(a)!
Pré requisitos
- Ruby
- Gem ffi
- GCC (para compilar o código em C)
Passo a Passo
Usando as Libs nativas do C
Neste exemplo nós vamos importar a função printf do C que permite a exibição de mensagens no console e depois vamos chama-la através do ruby.
1 – Para começar nós vamos instalar a gem ffi na nossa máquina rodando:
1 |
gem install ffi |
2 – Crie um arquivo chamando printf_c.rb.
3 – Importe nele o ffi colocando:
1 |
require 'ffi' |
4 – Agora crie um module para encapsularmos nossa Lib:
1 2 3 |
module MyLib end |
5 – Dentro do module inclua as libs do c colocando:
1 2 |
extend FFI::Library ffi_lib 'c' |
6 – Ainda dentro do module importe a função printf incluindo:
1 |
attach_function :printf, [ :string ], :int |
a – :printf : se refere ao nome da função nativa do C
b – [ :string ] : se refere ao tipo de parâmetro recebido por está função
c – :int : se refere ao tipo de retorno da função
7 – Agora após o module inclua a chamada da função:
1 |
MyLib.printf 'Hello, World using libc!' |
8 – Seu código final dever ser:
1 2 3 4 5 6 7 8 9 |
require 'ffi' module MyLib extend FFI::Library ffi_lib 'c' attach_function :printf, [ :string ], :int end MyLib.printf 'Hello, World using libc!' |
9 – Salve e chame no console:
1 |
ruby printf_c.rb |
10 – O resultado:
11 – Pronto, você acaba de usar uma função nativa do C através do Ruby.
Criando e usando uma Lib em C
Agora vamos aprender como criar uma Lib usando C e depois vamos chama-la direto do nosso código Ruby.
1 – Crie um arquivo chamado mult.c, nele vamos implementar o processo de multiplicação.
2 – No arquivo criado coloque:
1 2 3 4 5 6 |
#include <string.h> int mult(int a, int b) { int result = a * b; return result; } |
Basicamente nós criamos uma função que recebe dois parâmetros (a e b), depois criamos uma variável (result) para receber o resultado da multiplicação de a e b e por fim retornamos o valor.
3 – Para transformar este código em uma Lib executável vamos usar o GCC, rode no console:
1 2 |
gcc -c -fPIC mult.c -o mult.o gcc -shared mult.o -o mult.so |
4 – O resultado deve ser um arquivo mult.o e um arquivo executável mult.so.
5 – Agora crie um arquivo chamado mult.rb para importarmos e usarmos o mult.so.
6 – No arquivo criado coloque:
1 2 3 4 5 6 7 8 9 |
require 'ffi' module MyLib extend FFI::Library ffi_lib './mult.so' attach_function :mult, [:int, :int], :int end puts "Meu resultado: #{MyLib.mult 11,2}" |
a – Importamos o ffi
b – Criamos o module para importar a Lib
c – Com o ffi_lib importamos a lib mult.so
d – Com o attach_function importamos a função mult criada e descrevemos seus parâmetros e retorno
e – Por fim, executamos a função de multiplicação passando dois números aleatórios para serem multiplicados (11, 2)
7 – Execute o código acima rodando no console:
1 |
ruby mult.rb |
8 – O resultado:
9 – Pronto, você acaba de criar uma Lib C e utiliza-la no Ruby o/
Conclusão
Utilizar módulos do C ou C++ no Ruby não é um desafio tão grande, embora algumas Libs possam ser mais desafiadores de se usar do que o exemplo simples que foi demonstrado.
Para você se aprofundar mais nesta integração eu recomendo que você leia com calma a documentação da gem ffi e veja outros exemplos clicando aqui.
Raramente você vai precisar otimizar trechos ruby usando C ou C++, mas quando precisar você já sabe que pode fazer isto com tranquilidade.
Se você gostou deste artigo, deixe um comentário, fale sobre o OneBitCode com seus(uas) amigos(as) programadores(as) e se inscreva no nosso canal do Youtube no botão abaixo.
Grande abraço,
Leonardo Scorza