Vous êtes sur la page 1sur 9

I seriously want to start this relationship

with you, the readership with pure


honesty: I completely agree with the
incredibility of C. However, before we get
stuck into the detail, do you have any idea
about C extension and why you should
write one in 2016?
Heres a discussion of a real-world need
for a C extension in the Ruby language and
how a non-C developer can get it done
right.
Why would you want to write one in 2016?
There are two reasons behind it. One of
them is speed and another is leverage. If
there is a well defined problem and if
there is a need for speed, then writing an
extension can be a way to go.

Writing C Extension.
Sharing my personal experience, writing C
extension is a tough job and it an it advisable to go
with FFI dont use it, until you have no other
option. But, frankly speaking, I was scared of
writing C into widely used application.
Apart from FFI, there were great options like for
writing Ruby Extensions in Go, Crystal, Rust and
many other languages where C bindings can be
exposed. Anyways All I wanted to do is Go with C
extension.
clean C - rtosc
Considering several OSC and canonical
implementations, it made me use macros and
structs,which I didnt completely understand at the
time. I was about to give up and fortunately I
stumbled on the rtosc library. It is consisted with
two files rtosc.h and rtosc.c. Wishing the best
spirit of open source, I enquired on GitHub issue
and within few hours got a thoughtful and polite
response -viva la internet!

This helped me to try writing a C extension and


trust me Im glad that I did.
Source Code
https://www.xavierriley.co.uk/writing-a-cextension-for-ruby-in2016/?utm_source=rubyweekly&utm_medium=em
ail.
Getting started
Open Sound Control and the fast_osc API

OSC is a binary protocol that looks similar to RPC.


So the basic message might be looking something
like this:
/methodname, "sif", ["This is a string", 123, 3.14]
So here you can have a look at the type of the
arguments corresponds to a tag s for a string, i
for an int and for the Ruby API I decided to hide
this so you do not consider about types.
>> FastOsc.encode_single_message("/foo", ["baz", 1,
2.0]) =>
"/foo\x00\x00\x00\x00,sif\x00\x00\x00\x00baz\x00\x00\x0
0\x00\x01@\x00\x00\x00"

Its a tag string and an output array of the


encoded versions.
Rubys C API
Working out the type
switch(TYPE(current_arg))

Ints and Longs


case T_FIXNUM
Floats

case T_FLOAT:
To convert from Ruby to C NUM2DBL
Strings and Symbols
case T_STRING:
To convert Ruby symbols use rb_sym_to_s().

Unicode Strings
I had broken Unicode strings. However it needs to
be fixed so did my job this way.
string_arg = rb_str_new2(string_from_c);
enc = rb_enc_find_index("UTF-8");
rb_enc_associate_index(string_arg, enc);
Ruby Time objects
Start with the object type
case T_DATA:
It means you have Ruby object and you can
specifically check using
if (CLASS_OF(current_arg) == rb_cTime)

OSC Timestamps (NTP)

further reading

oscruby non-optimised library for Ruby.


samosc is hand rolled optimization for pure Ruby
version and fast_osc is this C extension. So it is like
4x improvement in Encoding to OSC and a 10x
improvement in Decoding over the fastest pure Ruby
implementation. It was done completely in a
successful way.
The code is available here:
https://github.com/xavriley/fast_osc.
Inspired to write your own extension, or have any
valuable feedback for my C extension. I would love
to hear from you. I am @bacancytech Twitter.
Thanks for reading.

Vous aimerez peut-être aussi