C API Reference
This document covers the mruby C API for embedding and extending mruby.
Contents: Headers | State Management | Values | Defining Classes and Modules | Defining Methods | Parsing Arguments | Calling Ruby Methods from C | String Operations | Array Operations | Hash Operations | Wrapping C Structures | Exception Handling | Method Visibility | Proc and Block Handling | Fiber API | Compilation Contexts | Precompiled Bytecode | GC Arena | Memory Allocation
Headers
#include <mruby.h> /* core types, state, class/method definition */
#include <mruby/compile.h> /* mrb_load_string, mrb_load_file */
#include <mruby/string.h> /* string operations */
#include <mruby/array.h> /* array operations */
#include <mruby/hash.h> /* hash operations */
#include <mruby/data.h> /* wrapping C structs */
#include <mruby/class.h> /* class inspection */
#include <mruby/value.h> /* value type macros */
#include <mruby/irep.h> /* loading precompiled bytecode */
#include <mruby/error.h> /* error handling (mrb_protect etc.) */
#include <mruby/variable.h> /* instance/class/global variables */
State Management
mrb_state *mrb = mrb_open(); /* create state with all gems */
mrb_state *mrb = mrb_open_core(); /* create state without gems */
mrb_close(mrb); /* close and free state */
mrb_open() returns NULL on allocation failure. Always check the
return value.
Values
All Ruby values are represented as mrb_value in C.
Creating Values
mrb_nil_value() /* nil */
mrb_true_value() /* true */
mrb_false_value() /* false */
mrb_bool_value(mrb_bool b) /* true or false */
mrb_fixnum_value(mrb_int i) /* Integer */
mrb_float_value(mrb_state *mrb, mrb_float f) /* Float */
mrb_symbol_value(mrb_sym sym) /* Symbol */
mrb_obj_value(void *p) /* object pointer to value */
mrb_cptr_value(mrb_state *mrb, void *p) /* C pointer */
Type Checking
mrb_type(v) /* returns enum mrb_vtype */
mrb_nil_p(v) /* true if nil */
mrb_integer_p(v) /* true if Integer */
mrb_float_p(v) /* true if Float */
mrb_symbol_p(v) /* true if Symbol */
mrb_string_p(v) /* true if String */
mrb_array_p(v) /* true if Array */
mrb_hash_p(v) /* true if Hash */
mrb_true_p(v) /* true if true */
mrb_false_p(v) /* true if false */
mrb_undef_p(v) /* true if undefined */
mrb_immediate_p(v) /* true if not a heap object */
Extracting C Values
mrb_integer(v) /* mrb_int from Integer value */
mrb_float(v) /* mrb_float from Float value */
mrb_symbol(v) /* mrb_sym from Symbol value */
mrb_ptr(v) /* void* from object value */
mrb_str_to_cstr(mrb, v) /* const char* from String value */
Value Types
mrb_vtype |
Ruby Class | Notes |
|---|---|---|
MRB_TT_FALSE |
FalseClass/NilClass | nil has MRB_TT_FALSE |
MRB_TT_TRUE |
TrueClass | |
MRB_TT_INTEGER |
Integer | Immediate value |
MRB_TT_FLOAT |
Float | May be immediate |
MRB_TT_SYMBOL |
Symbol | Immediate value |
MRB_TT_STRING |
String | Heap object |
MRB_TT_ARRAY |
Array | Heap object |
MRB_TT_HASH |
Hash | Heap object |
MRB_TT_OBJECT |
Object | User-defined classes |
MRB_TT_CLASS |
Class | |
MRB_TT_MODULE |
Module | |
MRB_TT_PROC |
Proc | |
MRB_TT_CDATA |
(C data) | Wrapped C structs |
MRB_TT_EXCEPTION |
Exception | |
MRB_TT_FIBER |
Fiber |
Defining Classes and Modules
/* Define a class under Object */
struct RClass *my_class = mrb_define_class(mrb, "MyClass", mrb->object_class);
/* Define a class under another class/module */
struct RClass *inner = mrb_define_class_under(mrb, outer, "Inner", mrb->object_class);
/* Define a module */
struct RClass *my_mod = mrb_define_module(mrb, "MyModule");
struct RClass *inner_mod = mrb_define_module_under(mrb, outer, "InnerMod");
/* Include/prepend a module */
mrb_include_module(mrb, my_class, my_mod);
mrb_prepend_module(mrb, my_class, my_mod);
/* Look up existing class/module */
struct RClass *c = mrb_class_get(mrb, "String");
struct RClass *m = mrb_module_get(mrb, "Kernel");
/* Define a constant */
mrb_define_const(mrb, my_class, "VERSION", mrb_str_new_lit(mrb, "1.0"));
Defining Methods
All C methods have the same signature:
static mrb_value
my_method(mrb_state *mrb, mrb_value self)
{
/* self is the receiver */
return mrb_nil_value();
}
Register with:
mrb_define_method(mrb, klass, "name", my_method, MRB_ARGS_NONE());
mrb_define_class_method(mrb, klass, "name", my_method, MRB_ARGS_REQ(1));
mrb_define_module_function(mrb, mod, "name", my_method, MRB_ARGS_ANY());
Argument Specifiers
| Macro | Meaning |
|---|---|
MRB_ARGS_NONE() |
No arguments |
MRB_ARGS_REQ(n) |
n required arguments |
MRB_ARGS_OPT(n) |
n optional arguments |
MRB_ARGS_ARG(r,o) |
r required + o optional |
MRB_ARGS_REST() |
Splat (*args) |
MRB_ARGS_BLOCK() |
Block (&block) |
MRB_ARGS_ANY() |
Any number (same as REST) |
MRB_ARGS_KEY(n,rest) |
n keyword args, rest=1 for **kw |
These can be combined with |:
MRB_ARGS_REQ(1) | MRB_ARGS_OPT(2) | MRB_ARGS_BLOCK()
Parsing Arguments
mrb_get_args() extracts arguments from the Ruby call stack:
mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...);
Format Specifiers
| Spec | Ruby Type | C Type(s) | Notes | |
|---|---|---|---|---|
o |
any | mrb_value |
No type check | |
i |
Numeric | mrb_int |
Coerces to integer | |
f |
Numeric | mrb_float |
Coerces to float | |
b |
any | mrb_bool |
Truthiness | |
n |
String/Symbol | mrb_sym |
Converts to symbol | |
s |
String | const char*, mrb_int |
Pointer + length | |
z |
String | const char* |
Null-terminated | |
S |
String | mrb_value |
String value | |
A |
Array | mrb_value |
Array value | |
H |
Hash | mrb_value |
Hash value | |
C |
Class | mrb_value |
Class/Module value | |
c |
Class | struct RClass* |
Class pointer | |
a |
Array | const mrb_value*, mrb_int |
Array pointer + length | |
d |
C Data | void* |
Requires mrb_data_type* |
|
& |
Block | mrb_value |
Block argument | |
* |
rest | const mrb_value*, mrb_int |
Rest arguments | |
| `\ | ` | — | — | Following args are optional |
? |
— | mrb_bool |
Was previous optional arg given? | |
: |
keywords | mrb_kwargs |
Keyword arguments |
Adding ! to S, A, H, C, c, s, z, a, d allows nil
(returns NULL/zero for nil).
Examples
/* def method(name, count) */
const char *name; mrb_int len, count;
mrb_get_args(mrb, "si", &name, &len, &count);
/* def method(required, optional=nil) */
mrb_value req, opt = mrb_nil_value();
mrb_get_args(mrb, "o|o", &req, &opt);
/* def method(*args) */
const mrb_value *args; mrb_int argc;
mrb_get_args(mrb, "*", &args, &argc);
/* def method(&block) */
mrb_value block;
mrb_get_args(mrb, "&", &block);
/* def method(name:, age: 0) */
mrb_sym kw_names[] = { mrb_intern_lit(mrb, "name"), mrb_intern_lit(mrb, "age") };
mrb_value kw_values[2];
mrb_kwargs kw = { 2, 1, kw_names, kw_values, NULL };
mrb_get_args(mrb, ":", &kw);
/* kw_values[0] = name (required), kw_values[1] = age (optional, undef if not given) */
Calling Ruby Methods from C
/* Call obj.method(arg1, arg2) */
mrb_funcall(mrb, obj, "method", 2, arg1, arg2);
/* Call with symbol (faster, no string lookup) */
mrb_funcall_id(mrb, obj, mrb_intern_lit(mrb, "method"), 2, arg1, arg2);
/* Call with argv array */
mrb_value argv[] = { arg1, arg2 };
mrb_funcall_argv(mrb, obj, mrb_intern_lit(mrb, "method"), 2, argv);
/* Call with block */
mrb_funcall_with_block(mrb, obj, mid, argc, argv, block);
/* Yield to block */
mrb_yield(mrb, block, arg);
mrb_yield_argv(mrb, block, argc, argv);
String Operations
/* Creation */
mrb_str_new_lit(mrb, "hello") /* from string literal */
mrb_str_new(mrb, ptr, len) /* from pointer + length */
mrb_str_new_cstr(mrb, cstr) /* from null-terminated C string */
mrb_str_new_static(mrb, ptr, len) /* from static data (no copy) */
/* Access */
RSTRING_PTR(str) /* char* pointer */
RSTRING_LEN(str) /* length */
mrb_str_to_cstr(mrb, str) /* null-terminated (may copy) */
/* Modification */
mrb_str_cat(mrb, str, ptr, len) /* append bytes */
mrb_str_cat_cstr(mrb, str, cstr) /* append C string */
mrb_str_cat_str(mrb, str, str2) /* append String */
/* Comparison */
mrb_str_equal(mrb, str1, str2) /* equality */
mrb_str_cmp(mrb, str1, str2) /* comparison (-1, 0, 1) */
Array Operations
/* Creation */
mrb_ary_new(mrb) /* empty array */
mrb_ary_new_capa(mrb, capa) /* preallocated */
mrb_ary_new_from_values(mrb, n, vals) /* from C array */
/* Access */
RARRAY_PTR(ary) /* mrb_value* pointer */
RARRAY_LEN(ary) /* length */
mrb_ary_entry(ary, idx) /* get element (no mrb needed) */
/* Modification */
mrb_ary_push(mrb, ary, val) /* append */
mrb_ary_pop(mrb, ary) /* remove last */
mrb_ary_shift(mrb, ary) /* remove first */
mrb_ary_unshift(mrb, ary, val) /* prepend */
mrb_ary_set(mrb, ary, idx, val) /* set element */
mrb_ary_splice(mrb, ary, pos, len, rpl) /* splice */
mrb_ary_concat(mrb, ary, other) /* extend */
Hash Operations
/* Creation */
mrb_hash_new(mrb) /* empty hash */
/* Access */
mrb_hash_get(mrb, hash, key) /* get value */
mrb_hash_fetch(mrb, hash, key, def) /* get with default */
mrb_hash_key_p(mrb, hash, key) /* key exists? */
mrb_hash_empty_p(mrb, hash) /* empty? */
mrb_hash_size(mrb, hash) /* number of entries */
/* Modification */
mrb_hash_set(mrb, hash, key, val) /* set key-value */
mrb_hash_delete_key(mrb, hash, key) /* delete key */
mrb_hash_merge(mrb, hash1, hash2) /* merge hash2 into hash1 */
/* Iteration */
mrb_hash_keys(mrb, hash) /* Array of keys */
mrb_hash_values(mrb, hash) /* Array of values */
Wrapping C Structures
To expose a C struct to Ruby, use mrb_data_type and Data_Wrap_Struct:
/* 1. Define the data type with a name and destructor */
static void point_free(mrb_state *mrb, void *p) {
mrb_free(mrb, p);
}
static const mrb_data_type point_type = {
"Point", point_free
};
/* 2. Allocate and initialize */
static mrb_value
point_init(mrb_state *mrb, mrb_value self)
{
mrb_float x, y;
mrb_get_args(mrb, "ff", &x, &y);
double *data = (double*)mrb_malloc(mrb, sizeof(double) * 2);
data[0] = x;
data[1] = y;
DATA_PTR(self) = data;
DATA_TYPE(self) = &point_type;
return self;
}
/* 3. Access the wrapped data */
static mrb_value
point_x(mrb_state *mrb, mrb_value self)
{
double *data = (double*)mrb_data_get_ptr(mrb, self, &point_type);
return mrb_float_value(mrb, data[0]);
}
/* 4. Register the class */
struct RClass *point = mrb_define_class(mrb, "Point", mrb->object_class);
MRB_SET_INSTANCE_TT(point, MRB_TT_CDATA);
mrb_define_method(mrb, point, "initialize", point_init, MRB_ARGS_REQ(2));
mrb_define_method(mrb, point, "x", point_x, MRB_ARGS_NONE());
Exception Handling
Raising Exceptions
mrb_raise(mrb, E_RUNTIME_ERROR, "something went wrong");
mrb_raisef(mrb, E_ARGUMENT_ERROR, "expected %d, got %d", expected, actual);
mrb_raise(mrb, E_TYPE_ERROR, "wrong type");
Common exception classes: E_RUNTIME_ERROR, E_TYPE_ERROR,
E_ARGUMENT_ERROR, E_RANGE_ERROR, E_NAME_ERROR,
E_NOMETHOD_ERROR, E_NOTIMP_ERROR, E_KEY_ERROR.
Catching Exceptions
/* Check after mrb_load_string or mrb_funcall */
mrb_value result = mrb_load_string(mrb, code);
if (mrb->exc) {
mrb_print_error(mrb);
mrb->exc = NULL; /* clear exception */
}
Protected Execution
mrb_protect() executes a function under protection. If an
exception is raised, it is captured as a return value instead of
propagating:
static mrb_value
safe_operation(mrb_state *mrb, mrb_value data)
{
/* This function might raise an exception */
return mrb_funcall(mrb, data, "do_something", 0);
}
mrb_bool error;
mrb_value result = mrb_protect(mrb, safe_operation, data, &error);
if (error) {
/* result contains the exception object; mrb->exc is cleared */
mrb_value inspect = mrb_inspect(mrb, result);
fprintf(stderr, "Error: %s\n", mrb_str_to_cstr(mrb, inspect));
}
Note: mrb_protect clears mrb->exc after catching the
exception. The exception is returned as result. Do not use
mrb_print_error() after mrb_protect — it reads mrb->exc
which is already NULL.
For lower-level protection with a void* callback:
static mrb_value
body(mrb_state *mrb, void *userdata)
{
/* ... */
}
mrb_bool error;
mrb_value result = mrb_protect_error(mrb, body, userdata, &error);
Rescue
mrb_rescue() catches StandardError (like Ruby's rescue):
static mrb_value
body_func(mrb_state *mrb, mrb_value body_data)
{
return mrb_funcall(mrb, body_data, "risky_method", 0);
}
static mrb_value
rescue_func(mrb_state *mrb, mrb_value rescue_data)
{
/* handle error, rescue_data is the data passed in */
return mrb_nil_value();
}
mrb_value result = mrb_rescue(mrb, body_func, body_data,
rescue_func, rescue_data);
To rescue specific exception classes:
struct RClass *classes[] = {
E_ARGUMENT_ERROR,
mrb_class_get(mrb, "IOError")
};
mrb_value result = mrb_rescue_exceptions(mrb, body_func, body_data,
rescue_func, rescue_data,
2, classes);
Ensure
mrb_ensure() guarantees cleanup runs regardless of exceptions
(like Ruby's ensure):
static mrb_value
body_func(mrb_state *mrb, mrb_value data)
{
return mrb_funcall(mrb, data, "process", 0);
}
static mrb_value
cleanup_func(mrb_state *mrb, mrb_value data)
{
mrb_funcall(mrb, data, "close", 0);
return mrb_nil_value();
}
mrb_value result = mrb_ensure(mrb, body_func, body_data,
cleanup_func, cleanup_data);
The ensure function always executes. If the body raises an exception, the ensure runs and then the exception is re-raised.
Error State Management
mrb_bool mrb_check_error(mrb_state *mrb); /* check and clear mrb->exc */
void mrb_clear_error(mrb_state *mrb); /* clear mrb->exc */
Method Visibility
/* Public (default) */
mrb_define_method(mrb, klass, "name", func, MRB_ARGS_NONE());
/* Private - only callable without explicit receiver */
mrb_define_private_method(mrb, klass, "name", func, MRB_ARGS_NONE());
/* Class method (singleton method on the class object) */
mrb_define_class_method(mrb, klass, "name", func, MRB_ARGS_NONE());
/* Module function (both module method and private instance method) */
mrb_define_module_function(mrb, mod, "name", func, MRB_ARGS_NONE());
/* Singleton method on a specific object */
mrb_define_singleton_method(mrb, obj, "name", func, MRB_ARGS_NONE());
/* Method alias: alias new_name old_name */
mrb_define_alias(mrb, klass, "new_name", "old_name");
/* Remove a method */
mrb_undef_method(mrb, klass, "name");
mrb_undef_class_method(mrb, klass, "name");
All _method variants have _id counterparts that accept
mrb_sym instead of const char* for better performance.
Proc and Block Handling
Creating Procs from C Functions
/* Simple C function proc */
struct RProc *proc = mrb_proc_new_cfunc(mrb, my_func);
/* C closure with captured local variables */
struct RProc *proc = mrb_closure_new_cfunc(mrb, my_func, nlocals);
C Functions with Environment (requires mruby-proc-ext)
Store values in a proc's environment, accessible from the C function:
mrb_value env_values[] = { mrb_fixnum_value(42) };
struct RProc *proc = mrb_proc_new_cfunc_with_env(mrb, my_func, 1, env_values);
/* Inside my_func, retrieve environment values */
static mrb_value my_func(mrb_state *mrb, mrb_value self)
{
mrb_value val = mrb_proc_cfunc_env_get(mrb, 0); /* index 0 */
return val;
}
Fiber API
#include <mruby.h> /* fiber types and functions */
Creating and Using Fibers
/* Create a fiber from a proc */
mrb_value fiber = mrb_fiber_new(mrb, proc);
/* Resume the fiber with arguments */
mrb_value args[] = { mrb_fixnum_value(1) };
mrb_value result = mrb_fiber_resume(mrb, fiber, 1, args);
/* Check if fiber is still alive */
mrb_bool alive = mrb_test(mrb_fiber_alive_p(mrb, fiber));
Yielding from C
mrb_fiber_yield() can only be used as the return value of a C
function — no code may execute after it:
static mrb_value
my_yield_method(mrb_state *mrb, mrb_value self)
{
mrb_value yield_args[] = { mrb_str_new_lit(mrb, "yielded") };
return mrb_fiber_yield(mrb, 1, yield_args); /* must be returned directly */
}
Fiber States
| State | Meaning |
|---|---|
MRB_FIBER_CREATED |
Created but not yet resumed |
MRB_FIBER_RUNNING |
Currently executing |
MRB_FIBER_RESUMED |
Resumed another fiber |
MRB_FIBER_SUSPENDED |
Yielded, waiting to resume |
MRB_FIBER_TRANSFERRED |
Transferred via Fiber#transfer |
MRB_FIBER_TERMINATED |
Finished execution |
Limitation: fibers cannot yield across C function boundaries.
You cannot call mrb_fiber_yield from within a C-implemented
method, except via mrb_fiber_yield at function return.
Compilation Contexts
For advanced compilation control, use mrb_ccontext:
#include <mruby/compile.h>
mrb_ccontext *cxt = mrb_ccontext_new(mrb);
/* Set source filename for error messages and debug info */
mrb_ccontext_filename(mrb, cxt, "my_script.rb");
/* Compile and execute with context */
mrb_value result = mrb_load_string_cxt(mrb, "1 + 2", cxt);
/* Clean up */
mrb_ccontext_free(mrb, cxt);
Context Options
The mrb_ccontext structure provides several flags:
| Field | Purpose |
|---|---|
capture_errors |
Collect parse errors instead of raising |
no_exec |
Compile without executing (get RProc) |
no_optimize |
Disable peephole optimizations |
no_ext_ops |
Disable extended operand instructions |
keep_lv |
Preserve local variables across loads |
Loading with Context
mrb_load_string_cxt(mrb, code, cxt); /* string + context */
mrb_load_nstring_cxt(mrb, code, len, cxt); /* with explicit length */
mrb_load_file_cxt(mrb, fp, cxt); /* file + context */
mrb_load_detect_file_cxt(mrb, fp, cxt); /* auto-detect .mrb or .rb */
Precompiled Bytecode
Load .mrb files compiled by mrbc:
#include <mruby/irep.h>
/* From byte array (generated by mrbc -B) */
mrb_value result = mrb_load_irep(mrb, bytecode);
/* From buffer with explicit size (safer, bounds-checked) */
mrb_value result = mrb_load_irep_buf(mrb, buf, size);
/* From file */
FILE *fp = fopen("script.mrb", "rb");
mrb_value result = mrb_load_irep_file(mrb, fp);
fclose(fp);
/* Load without executing (returns irep for inspection) */
mrb_irep *irep = mrb_read_irep(mrb, bytecode);
All _irep loading functions have _cxt variants that accept
a compilation context.
Deployment Pattern
Ahead-of-time compilation eliminates the need for the compiler gem at runtime:
# Compile to C array
mrbc -Bscript_bytecode script.rb
# This generates a C header with:
# const uint8_t script_bytecode[];
#include "script.mrb.h"
mrb_state *mrb = mrb_open_core(); /* no compiler needed */
mrb_load_irep(mrb, script_bytecode);
Important: wrap bytecode loading in arena save/restore when loading multiple scripts:
int ai = mrb_gc_arena_save(mrb);
mrb_load_irep(mrb, script1);
mrb_gc_arena_restore(mrb, ai);
ai = mrb_gc_arena_save(mrb);
mrb_load_irep(mrb, script2);
mrb_gc_arena_restore(mrb, ai);
Symbols
/* Create symbol from string */
mrb_sym sym = mrb_intern_lit(mrb, "name"); /* from literal */
mrb_sym sym = mrb_intern_cstr(mrb, cstr); /* from C string */
mrb_sym sym = mrb_intern(mrb, ptr, len); /* from pointer + length */
/* Symbol to string */
const char *name = mrb_sym_name(mrb, sym);
mrb_int len;
const char *name = mrb_sym_name_len(mrb, sym, &len);
Instance Variables
/* Get/set instance variables on an object */
mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@x"));
mrb_iv_set(mrb, obj, mrb_intern_lit(mrb, "@x"), val);
mrb_iv_defined(mrb, obj, mrb_intern_lit(mrb, "@x"));
mrb_iv_remove(mrb, obj, mrb_intern_lit(mrb, "@x"));
Global Variables
mrb_gv_get(mrb, mrb_intern_lit(mrb, "$verbose"));
mrb_gv_set(mrb, mrb_intern_lit(mrb, "$verbose"), mrb_true_value());
Class Variables
mrb_cv_get(mrb, klass, mrb_intern_lit(mrb, "@@count"));
mrb_cv_set(mrb, klass, mrb_intern_lit(mrb, "@@count"), mrb_fixnum_value(0));
Loading and Executing Code
/* Load and execute a string (requires mruby-compiler gem) */
mrb_value result = mrb_load_string(mrb, "1 + 2");
/* Load and execute a file */
FILE *f = fopen("script.rb", "r");
mrb_value result = mrb_load_file(mrb, f);
fclose(f);
/* Load precompiled bytecode (no compiler needed) */
mrb_value result = mrb_load_irep(mrb, bytecode_array);
GC Arena
When creating many temporary Ruby objects in C, use the GC arena to prevent them from being collected prematurely:
int ai = mrb_gc_arena_save(mrb);
/* create temporary objects here */
mrb_gc_arena_restore(mrb, ai);
See gc-arena-howto.md for details.
Memory Allocation
void *p = mrb_malloc(mrb, size); /* raises on failure */
void *p = mrb_calloc(mrb, nmemb, size); /* zero-initialized */
void *p = mrb_realloc(mrb, ptr, size); /* resize */
mrb_free(mrb, p); /* free */
/* NULL-returning variants (for custom error handling) */
void *p = mrb_malloc_simple(mrb, size);
void *p = mrb_realloc_simple(mrb, ptr, size);
Type Conversion
mrb_obj_as_string(mrb, val) /* to_s */
mrb_inspect(mrb, val) /* inspect */
mrb_any_to_s(mrb, val) /* default to_s */
mrb_str_to_integer(mrb, str, base, badcheck) /* String to Integer */
mrb_str_to_dbl(mrb, str, badcheck) /* String to Float */
mrb_ensure_float_type(mrb, val) /* ensure Float */
Object Comparison
mrb_equal(mrb, a, b) /* Ruby == */
mrb_eql(mrb, a, b) /* Ruby eql? */
mrb_obj_eq(mrb, a, b) /* Ruby equal? (identity) */
mrb_cmp(mrb, a, b) /* Ruby <=> (returns mrb_int) */
Object Inspection
mrb_obj_classname(mrb, obj) /* class name as C string */
mrb_obj_class(mrb, obj) /* class as RClass* */
mrb_obj_is_kind_of(mrb, obj, klass) /* is_a? / kind_of? */
mrb_obj_respond_to(mrb, klass, mid) /* respond_to? */
mrb_obj_id(obj) /* object_id */
mrb_obj_freeze(mrb, obj) /* freeze */
mrb_obj_dup(mrb, obj) /* dup */
Compile-Time Flags
When compiling C code that uses mruby, you must use the same flags as
the library was built with. Use mruby-config to get them:
$ build/host/bin/mruby-config --cflags # compiler flags
$ build/host/bin/mruby-config --ldflags # linker flags
$ build/host/bin/mruby-config --libs # libraries
Key macros that affect ABI:
| Macro | Effect |
|---|---|
MRB_NO_BOXING |
Struct-based values (larger, debuggable) |
MRB_WORD_BOXING |
Single-word values (fast, 32-bit safe) |
MRB_NAN_BOXING |
NaN-tagged values (default on 32-bit) |
MRB_NO_FLOAT |
Disable Float support |
MRB_INT64 |
64-bit integers |
MRB_USE_FLOAT32 |
32-bit floats |
Mismatching these between library and application causes silent data corruption.