Last active
September 10, 2020 17:41
-
-
Save mrryanjohnston/888f885bae37da37cb2ea9be61c78569 to your computer and use it in GitHub Desktop.
ruby c extension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ruby.h" | |
#include "foo_class.h" | |
VALUE CExtensionModule = Qnil; | |
void Init_c_extension() | |
{ | |
CExtensionModule = rb_define_module("CExtension"); | |
rb_init_foo_class(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'mkmf' | |
create_makefile('c_extension') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "foo_class.h" | |
VALUE FooClass = Qnil; | |
VALUE ExampleStructClass = Qnil; | |
extern VALUE CExtensionModule; | |
typedef struct example_struct { | |
char *name; | |
int struct_id; | |
} example_struct; | |
static VALUE rb_example_struct_init(VALUE self, VALUE name) { | |
example_struct* p; | |
Check_Type(name, T_STRING); | |
Data_Get_Struct(self, example_struct, p); | |
p->name = (char *)malloc(RSTRING_LEN(name) + 1); | |
memcpy(p->name, StringValuePtr(name), RSTRING_LEN(name) + 1); | |
return self; | |
} | |
static VALUE rb_example_struct_name(VALUE self) { | |
example_struct* p; | |
Data_Get_Struct(self, example_struct, p); | |
return rb_str_new_cstr(p->name); | |
} | |
void rb_init_foo_class() | |
{ | |
FooClass = rb_define_class_under(CExtensionModule, "FooClass", rb_cObject); | |
rb_define_method(FooClass, "say_hi", rb_foo_class_say_hi, 0); | |
rb_define_method(FooClass, "say_hi_to", rb_foo_class_say_hi_to, 1); | |
ExampleStructClass = rb_define_class_under(CExtensionModule, "ExampleStructClass", rb_cObject); | |
rb_define_alloc_func(ExampleStructClass, rb_foo_class_struct_alloc); | |
rb_define_method(ExampleStructClass, "initialize", rb_example_struct_init, 1); | |
rb_define_method(ExampleStructClass, "name", rb_example_struct_name, 0); | |
} | |
VALUE rb_foo_class_say_hi(VALUE self) | |
{ | |
return rb_str_new2("Hello!"); | |
} | |
VALUE rb_foo_class_say_hi_to(VALUE self, VALUE r_name) | |
{ | |
VALUE r_greeting = rb_str_new2("Hello, "); | |
rb_str_append(r_greeting, r_name); | |
return r_greeting; | |
} | |
void example_struct_free(example_struct * self) { | |
if (self->name != NULL) { | |
free(self->name); | |
} | |
ruby_xfree(self); | |
} | |
VALUE rb_foo_class_struct_alloc(VALUE self) | |
{ | |
return Data_Wrap_Struct(self, NULL, example_struct_free, ruby_xmalloc(sizeof(example_struct))); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ruby.h" | |
void rb_init_foo_class(); | |
VALUE rb_foo_class_say_hi(VALUE self); | |
VALUE rb_foo_class_say_hi_to(VALUE self, VALUE r_name); | |
VALUE rb_foo_class_struct(VALUE self, VALUE r_bar); | |
VALUE rb_foo_class_struct_alloc(VALUE klass); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "bundler/gem_tasks" | |
require "rake/testtask" | |
require "rake/extensiontask" | |
Rake::TestTask.new(:test) do |t| | |
t.libs << "test" | |
t.libs << "lib" | |
t.test_files = FileList["test/**/*_test.rb"] | |
end | |
Rake::ExtensionTask.new("c_extension") do |ext| | |
ext.lib_dir = "lib/c_extension" | |
end | |
task :default => :test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "test_helper" | |
class CExtensionTest < Minitest::Test | |
def test_that_it_has_a_version_number | |
refute_nil ::CExtension::VERSION | |
end | |
def test_it_says_hi | |
assert "Hello!", CExtension::FooClass.new.say_hi | |
end | |
def test_it_says_hi_to_bob | |
assert "Hello, Bob", CExtension::FooClass.new.say_hi_to("Bob") | |
end | |
def test_struct | |
assert_equal 'a', CExtension::ExampleStructClass.new('a').name | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment