# Embeddable / Interoperable with ruby

**URL:** <https://forum.crystal-lang.org/t/embeddable-interoperable-with-ruby/4894>\
**Category:** Crystal Contrib\
**Created:** [August 28, 2022, 11:13am UTC](https://forum.crystal-lang.org/t/embeddable-interoperable-with-ruby/4894 "2022-08-28T11:13:35Z")\
**Posts on this page:** 1\
**Showing post:** 19

<div class="post-metadata">

**Author:** ![OldFart](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/oldfart/32/1748_2.png) [@OldFart](https://forum.crystal-lang.org/u/OldFart)\
**Post date:** [August 31, 2022, 7:22pm UTC](https://forum.crystal-lang.org/t/embeddable-interoperable-with-ruby/4894/19 "2022-08-31T19:22:31Z")

</div>

My adventures with the subject:  
I was able to compile Crystal code to shared library (MacOS `dylib`), link it with some glue code in C and load it as C extension in ruby. I was able to call Crystal `fun` from ruby, and that fun was able to instantiate object and call instance method on that object. Looks like GC works. No segfault for now  
Crystal file:

```crystal
class SomeClass
    def do_something(num : Int32)
        num*3+3
    end
end

FAKE_ARG = "crystal"

fun __crystal_init
    GC.init
    ptr = FAKE_ARG.to_unsafe
    LibCrystalMain.__crystal_main(1, pointerof(ptr))
end

fun __crystal_module_run
    puts "Crystal module run"
    test_add(1, 2)
end

def test_add(x, y)
    r = x + y + 3
    res = SomeClass.new().do_something(r)

    puts "Got #{r} and #{res}"
    res
end

res = test_add(1, 2)

puts res

```

Compile with

```bash
crystal build test.cr --link-flags "-shared" -o libcrystal_module.dylib

```

Ruby c extension code:

```nohighlight
#include <ruby.h>
#include "extconf.h"

extern void __crystal_init();
extern void __crystal_module_run();

VALUE test_cfunc(VALUE _self, VALUE num) {
    int n = NUM2INT(num);
    VALUE result = INT2NUM(n+1);
    return result;
}

VALUE test_module_run(VALUE _self) {
    __crystal_module_run();
    return Qnil;
}

void Init_crystal() {
    VALUE mod = rb_define_module("TestModule");
    __crystal_init();
    rb_define_module_function(mod, "test", test_cfunc, 1);
    rb_define_module_function(mod, "dry_run", test_module_run, 0);
}

```

To link shared library to ruby C extension, I had to add

```ruby
$LDFLAGS << " -L#{File.expand_path("#{ __dir__ }/../../crystal",)} -lcrystal_module"

```

to extconf.rb

Everything works as expected, but that is not much

Next, I need to process Crystal code and generate ruby wrappers, and load code dynamically.  
First of all, I’ll try to compile Crystal code to MacOS `bundle` file and load it using `dlload`. I’ll add one more `fun` to Crystal code (lets call it `__crystal_load_module`) that will add Crystal wrappers to ruby.  
I looked how [Anyolite](https://forum.crystal-lang.org/t/anyolite-1-0-0/4630) does that, and I’m thinking how can I either implement something similar or reuse existing code. I’m impressed what they were able to achieve with crippled Crystal macros and annotations.  
I can’t link Crystal code to ruby API dorectly, so I think I’ll pass a struct with ruby API function pointers to `__crystal_load_module`.

---

_[View the full topic](https://forum.crystal-lang.org/t/embeddable-interoperable-with-ruby/4894)._
