mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
accessing C from Ruby part
@@ -1,12 +1,12 @@
|
||||
## 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.
|
||||
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. Or define everything in C. Your choice.
|
||||
|
||||
### 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:
|
||||
Create a file `wiki-example.rb` with the following content. This class is already prepared for the next section (manipulating Ruby classes from C). We now only need the 'get_version' method.
|
||||
|
||||
`````
|
||||
module WikiExample
|
||||
@@ -74,4 +74,37 @@ Compile this code with `gcc -std=c99 -Iinclude wiki-example.c build/host/lib/l
|
||||
|
||||
### Calling C methods from Ruby
|
||||
|
||||
Coming soon...
|
||||
The strategy is first to update the existing class. Here we add a C-method to the class, but we can even define the module and class from C.
|
||||
|
||||
To add a method to a class, we first need a reference to the class. We can copy the lines from the first example for getting a reference to the class WikiManager, of just insert the next lines just before the `If crashed...` comment line.
|
||||
|
||||
`````
|
||||
// add the method to the WikiManager class
|
||||
mrb_define_method(mrb, class, "_we_connected", we_connected, MRB_ARGS_NONE());
|
||||
|
||||
// call the connect method on WikiManager
|
||||
mrb_value res2 = mrb_funcall(mrb, c, "connect", 0);
|
||||
`````
|
||||
|
||||
Then we add the following method between the `#include` and `int main` lines:
|
||||
|
||||
`````
|
||||
mrb_value
|
||||
we_connected(mrb_state* mrb, mrb_value self){
|
||||
// we need an int from the args
|
||||
mrb_int i = 0;
|
||||
|
||||
// retrieve one arg of type int (see mruby.h)
|
||||
mrb_get_args(mrb, "i", &i);
|
||||
|
||||
// we always need to return a mrb_value object, and mrb_bool_value converts a C bool to a mrb_value.
|
||||
return mrb_bool_value(i >= 2);
|
||||
}
|
||||
`````
|
||||
|
||||
Compile (see above) and run. You will get the output `result: 2`. Now edit the Ruby file and change the get_version to return 1. Do not compile, just run the executable again, and see the output `result: 1
|
||||
Connection failed`.
|
||||
|
||||
This will give you unlimited results, as you don't even need to recompile to update your Ruby code. Image writing unit-tests in Ruby calling your C-methods in classes. You will be able to mock classes the Ruby-way.
|
||||
|
||||
Passing the arguments is quite straightforward (both ways). But someone might update this page with some code on how to pass a C struct to Ruby and use the result.
|
||||
Reference in New Issue
Block a user