Skip to content

Instantly share code, notes, and snippets.

@yalab
Last active June 5, 2019 11:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yalab/9025d01fdfc1cd1c695e3ca561f274ca to your computer and use it in GitHub Desktop.
Save yalab/9025d01fdfc1cd1c695e3ca561f274ca to your computer and use it in GitHub Desktop.
Bridge between C++ and ruby.

Try to implement C++ and ruby Bridge.

How to use

$ ruby extconf.rb
$ make
$ ruby test.rb
require 'mkmf'
have_library("stdc++")
$CXXFLAGS += '-std=c++14 -Wc++11-extensions -Wc++11-long-long'
create_makefile("foo")
#include "foo.h"
#include <iostream>
#include <new>
Foo::Foo(const char* name)
{
_init = true;
_name = name;
}
const char* Foo::say() const
{
std::cout << "This is foo in cpp ";
std::cout << _name << std::endl;
return _name;
}
static void wrap_Foo_free(Foo* p)
{
if(p->isInit()){
p->~Foo();
}
ruby_xfree(p);
}
static VALUE wrap_Foo_alloc(VALUE klass)
{
return Data_Wrap_Struct(klass, NULL, wrap_Foo_free, ruby_xmalloc(sizeof(Foo)));
}
static VALUE wrap_Foo_init(VALUE self, VALUE _name)
{
const char* name = StringValuePtr(_name);
Foo* p;
Data_Get_Struct(self, Foo, p);
new (p) Foo(name);
return Qnil;
}
static VALUE wrap_Foo_say(VALUE self)
{
Foo* p;
Data_Get_Struct(self, Foo, p);
return rb_str_new2(p->say());
}
extern "C" void Init_foo()
{
VALUE c = rb_define_class("Foo", rb_cObject);
rb_define_alloc_func(c, wrap_Foo_alloc);
rb_define_private_method(c, "initialize", RUBY_METHOD_FUNC(wrap_Foo_init), 1);
rb_define_method(c, "say", RUBY_METHOD_FUNC(wrap_Foo_say), 0);
}
#ifndef __FOO_H__
#define __FOO_H__
#include <ruby.h>
class Foo
{
public:
Foo(const char* name);
virtual ~Foo() = default;
inline bool isInit(){ return _init; }
const char* say() const;
private:
bool _init;
const char* _name;
};
#endif
require './foo'
p Foo.new("hoge").say
p Foo.new("baz").say
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment