From 38af9344d0e14e9903330e42905ef2897b3022b5 Mon Sep 17 00:00:00 2001 From: hlogmans Date: Fri, 5 Feb 2016 15:29:13 +0100 Subject: [PATCH] Example code loading and executing code, handling results and converting mrb_value to a value type. --- ...your-Ruby-environment-and-accessing-it..md | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Building-your-Ruby-environment-and-accessing-it..md diff --git a/Building-your-Ruby-environment-and-accessing-it..md b/Building-your-Ruby-environment-and-accessing-it..md new file mode 100644 index 0000000..b8ce69c --- /dev/null +++ b/Building-your-Ruby-environment-and-accessing-it..md @@ -0,0 +1,77 @@ +## Building your Ruby environment + +You can create classes both from C and Ruby together. Define the class in Ruby code just as a regular Ruby class, and then add C-code the manipulate the class definition. + +### Access Ruby from C + +Lets first define some class in Ruby code, and try to access this from C: + +Create a file `wiki-example.rb` with the following content: + +````` +module WikiExample + class WikiManager + attr_accessor :active + def connect + self.active = _we_connected + end + + def get_version + return 2 + end + + # _we_connected() is defined in C + end +end +````` + +Then we write a C stub and small program to access this code. We first initialize mruby, then load the code file and the third step is to access the module, class and instance method. + +Name the file `wiki-example.c`. +````` +#include "mruby.h" +#include "mruby/irep.h" + +int +main(void) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("wiki-example.rb","r"); + + // Load the data from the .rb file into the Ruby environment + mrb_value obj = mrb_load_file(mrb,fp); + + // close the file + fclose(fp); + + // First access the module + struct RClass *module = mrb_module_get(mrb, "WikiExample"); + + // Get the class that is defined in the WikiExample module + struct RClass *class = mrb_class_get_under(mrb, module, "WikiManager"); + + // Create a new instance of WikiManager, no arguments are needed (0, NULL) + mrb_value c = mrb_obj_new(mrb, class, 0, NULL); + + // Call the get_version method on the instance. + mrb_value res = mrb_funcall(mrb, c, "get_version", 0); + + // Convert the result (a fixed number wrapped in a mrb_value) + printf("result: %i\n", mrb_fixnum(res)); + + // If crashed, provide exception info + if (mrb->exc) + { + mrb_print_error(mrb); + } + // Close the Ruby environment + mrb_close(mrb); +} +````` + +Compile this code with `gcc -std=c99 -Iinclude wiki-example.c build/host/lib/libmruby.a -o wiki-example` and then run `wiki-example`. The output is `result: 2`. + +### Calling C methods from Ruby + +Coming soon...