Marcelo Junior
Posted on June 20, 2023
Creating a Gem using Ruby C API
Sometimes we want to use a lib built with C
language without any Ruby
version, to make this we'll find a gem that integrates the lib C
with Ruby
. But, how this Gem was built?
In this article I'll show how to make this, using as an example the project musicrb, this Gem uses the lib of C
vlc to play music on Ruby.
How is possible to integrate Ruby and C?
It's simple: Ruby
is built using C
, so we'll build a shared lib to the interpreter of Ruby
use.
But do not trust in me, see the repository of language!
Basic about Ruby C API
Before starting to code our lib, we'll see some features in Ruby C API that we will use (p.s.: this tutorial is very basic if you want deep in this theme, my recommendation is the book Ruby Under a Microscope).
VALUE
See VALUE as a pointer to a Ruby's Object
, since the Ruby
is dynamic this feature is required. Then String
, Number
, Class
, Module
... are accessed and modified by VALUE
through functions of Ruby C API
.
This is an example using VALUE
as a pointer to String
:
VALUE x;
x = rb_str_new_cstr("Hello, world!");
VALUE str;
str = rb_sprintf("pi = %f. %"PRIsVALUE" inspected: %+"PRIsVALUE, M_PI, x, x);
/* pi = 3.141593. Hello, world! inspected: "Hello, world!" */
We can see that isn't required to pass the type of VALUE to methods like a programRuby
!
DEFINE
The Gem musicrb
has a class
named Music
, and has two static methods: play
and stop
.
Define this class
and methods
using Ruby
is very simple:
class Music
def play
# Implementation ...
end
def stop
# Implementation ...
end
end
The code in C
will be like this:
// Headers ...
// Global variables ...
VALUE rb_cMusic;
VALUE
rb_music_stop(VALUE msc)
{
// Implementation ...
}
VALUE
rb_music_play(VALUE msc, VALUE rpath)
{
// Implementation ...
}
void
Init_musicrb(void)
{
rb_cMusic = rb_define_class("Music", rb_cObject);
rb_define_singleton_method(rb_cMusic, "play", rb_music_play, 1);
rb_define_singleton_method(rb_cMusic, "stop", rb_music_stop, 0);
}
rb_define_class
: Define a class named "Music" that has a heritage with "Object".
rb_define_singleton_method
: Define a singleton method to class "Music", in other words, a method of class. The last parameter of the function is the number of args.
Again, don't trust me!
See here the code.
Next steps
Okay, we already see the basics about the Ruby C API
, but how to compile and test this code?
This post is already too long... I will follow up on the subject in the next article!
Goodbye, see you soon!
Posted on June 20, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.