mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge pull request #5887 from rmalizia44/cdata-example
Add cdata example
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
# C Data Extension Example
|
||||
|
||||
This is an example gem which implements a C extension with Data.
|
||||
@@ -0,0 +1,23 @@
|
||||
MRuby::Gem::Specification.new('cdata_extension_example') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
|
||||
# Add compile flags
|
||||
# spec.cc.flags << '-g'
|
||||
|
||||
# Add cflags to all
|
||||
# spec.mruby.cc.flags << '-g'
|
||||
|
||||
# Add libraries
|
||||
# spec.linker.libraries << 'external_lib'
|
||||
|
||||
# Default build files
|
||||
# spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
|
||||
# spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) }
|
||||
# spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb")
|
||||
# spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) }
|
||||
# spec.test_preload = 'test/assert.rb'
|
||||
|
||||
# Values accessible as TEST_ARGS inside test scripts
|
||||
# spec.test_args = {'tmp_dir' => Dir::tmpdir}
|
||||
end
|
||||
@@ -0,0 +1,77 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/data.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void mrb_foo_free(mrb_state *mrb, void *ptr) {
|
||||
/* custom destructor */
|
||||
mrb_free(mrb, ptr);
|
||||
}
|
||||
struct mrb_data_type mrb_foo_type = { "Foo", mrb_foo_free };
|
||||
|
||||
struct Foo {
|
||||
int bar;
|
||||
char baz[32];
|
||||
};
|
||||
|
||||
static mrb_value
|
||||
mrb_foo_initialize(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct Foo *f;
|
||||
|
||||
f = (struct Foo*)mrb_malloc(mrb, sizeof(struct Foo));
|
||||
f->bar = 0;
|
||||
|
||||
DATA_PTR(self) = f;
|
||||
DATA_TYPE(self) = &mrb_foo_type;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_foo_get_bar(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct Foo *f;
|
||||
|
||||
f = (struct Foo*)mrb_data_get_ptr(mrb, self, &mrb_foo_type);
|
||||
if(f == NULL) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "uninitialized data");
|
||||
}
|
||||
|
||||
return mrb_fixnum_value(f->bar);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_foo_set_bar(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct Foo *f;
|
||||
int v;
|
||||
|
||||
f = (struct Foo*)mrb_data_get_ptr(mrb, self, &mrb_foo_type);
|
||||
if(f == NULL) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "uninitialized data");
|
||||
}
|
||||
|
||||
mrb_get_args(mrb, "i", &v);
|
||||
|
||||
f->bar = v;
|
||||
|
||||
return mrb_fixnum_value(f->bar);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_cdata_extension_example_gem_init(mrb_state* mrb) {
|
||||
struct RClass *class_foo;
|
||||
|
||||
class_foo = mrb_define_class(mrb, "Foo", mrb->object_class);
|
||||
MRB_SET_INSTANCE_TT(class_foo, MRB_TT_CDATA);
|
||||
mrb_define_method(mrb, class_foo, "initialize", mrb_foo_initialize, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, class_foo, "bar", mrb_foo_get_bar, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, class_foo, "bar=", mrb_foo_set_bar, MRB_ARGS_REQ(1));
|
||||
}
|
||||
|
||||
void
|
||||
mrb_cdata_extension_example_gem_final(mrb_state* mrb) {
|
||||
/* gem finalizer */
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <mruby.h>
|
||||
|
||||
void
|
||||
mrb_cdata_extension_example_gem_test(mrb_state *mrb)
|
||||
{
|
||||
/* test initializer in C */
|
||||
}
|
||||
Reference in New Issue
Block a user