#include #include #include #include #include #include #include #include #include struct my_class { int num; FILE *fp; }; static void mrb_my_class_free(mrb_state *mrb, void *ptr); // const static struct mrb_data_type mrb_my_class_type = {"MyClass", mrb_free}; const static struct mrb_data_type mrb_my_class_type = {"MyClass", mrb_my_class_free}; // class method mrb_value mrb_my_class_initialize(mrb_state *mrb, mrb_value self) { FILE *fp; struct my_class *h; mrb_value path; char *cpath; h = (struct my_class *)mrb_malloc(mrb, sizeof(struct my_class)); h->fp = NULL; DATA_TYPE(self) = &mrb_my_class_type; DATA_PTR(self) = h; mrb_get_args(mrb, "S", &path); cpath = mrb_str_to_cstr(mrb, path); fp = fopen(cpath, "r"); if (fp == NULL) { if (errno == EMFILE || errno == ENFILE) { mrb_full_gc(mrb); fp = fopen(cpath, "r"); } if (fp == NULL) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "Cannot open file: %s", path); } } h->num = 1234; h->fp = fp; return self; } mrb_value mrb_my_class_get(mrb_state *mrb, mrb_value self) { struct my_class *h = DATA_PTR(self); return mrb_fixnum_value(h->num); } mrb_value mrb_my_class_put(mrb_state *mrb, mrb_value self) { struct my_class *h = DATA_PTR(self); mrb_int num; mrb_get_args(mrb, "i", &num); h->num = num; return mrb_fixnum_value(num); } mrb_value mrb_my_class_read(mrb_state *mrb, mrb_value self) { struct my_class *h; size_t n; char buf[1024]; h = DATA_PTR(self); n = fread(buf, 1, sizeof(buf), h->fp); if (n == 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "fread(3) returns 0"); } return mrb_str_new(mrb, buf, n); } static void mrb_my_class_free(mrb_state *mrb, void *ptr) { struct my_class *h = ptr; if (h->fp != NULL) { fclose(h->fp); h->fp = NULL; } mrb_free(mrb, h); } int main(int argc, char *argv[]) { // open mruby state mrb_state *mrb = mrb_open(); if (mrb == 0) { printf("cannot open mruby state.\n"); return -2; } // define mruby class struct RClass *my_class; my_class = mrb_define_class(mrb, "MyClass", mrb->object_class); MRB_SET_INSTANCE_TT(my_class, MRB_TT_DATA); // define method mrb_define_method(mrb, my_class, "initialize", mrb_my_class_initialize, MRB_ARGS_NONE()); mrb_define_method(mrb, my_class, "get", mrb_my_class_get, MRB_ARGS_NONE()); mrb_define_method(mrb, my_class, "put", mrb_my_class_put, MRB_ARGS_REQ(1)); mrb_define_method(mrb, my_class, "read", mrb_my_class_read, MRB_ARGS_NONE()); // file open FILE *fp = fopen("main.rb", "r"); // run mruby script mrb_load_file(mrb, fp); // file close fclose(fp); // close mruby state mrb_close(mrb); return 0; }