Skip to content

Instantly share code, notes, and snippets.

@sojastar
Created September 4, 2022 17:52
Show Gist options
  • Save sojastar/fb30f040cbb184ad9874b9244a09dc21 to your computer and use it in GitHub Desktop.
Save sojastar/fb30f040cbb184ad9874b9244a09dc21 to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <stdio.h>
#include <mruby.h>
#include <mruby/compile.h>
/******************************************************************************
* 1. CONSTANTS :
******************************************************************************/
#define RUBY_CODE "c_from_ruby.rb"
/******************************************************************************
* 2. FUNCTION PROTOTYPES :
******************************************************************************/
mrb_value add_c(mrb_state *mrb,mrb_value self);
/******************************************************************************
* 3. MAIN :
******************************************************************************/
int main(void) {
// 3.1 Initializing mRuby :
mrb_state *mrb = mrb_open();
if (mrb == NULL) {
printf("Can't initilizing mRuby. Aborting.");
exit(1);
}
struct RClass *a_module = mrb_define_module(mrb, "AModule");
mrb_define_module_function(mrb, a_module, "add", add_c, MRB_ARGS_REQ(2));
// 3.2 Loading the Ruby source code :
FILE *ruby_code = fopen(RUBY_CODE, "r");
char *ruby_string = NULL;
if(ruby_code == NULL) {
printf("Can't open file %s. Aborting.", RUBY_CODE);
exit(1);
}
if (fseek(ruby_code, 0L, SEEK_END) == 0) {
long file_size = ftell(ruby_code);
ruby_string = malloc(sizeof(char) * (file_size + 1));
fseek(ruby_code, 0L, SEEK_SET);
size_t length = fread(ruby_string, sizeof(char), file_size, ruby_code);
ruby_string[length] = '\0';
}
// 3.3 Execute Ruby source code :
mrb_load_string(mrb, ruby_string);
mrb_close(mrb);
// 3.4 Cleanup :
free(ruby_string);
fclose(ruby_code);
return 0;
}
/******************************************************************************
* 4. FUNCTION DEFINITIONS :
******************************************************************************/
mrb_value add_c(mrb_state *mrb,mrb_value self) {
mrb_int a, b;
mrb_get_args(mrb, "ii", &a, &b); // getting the arguments according to :
// https://github.com/mruby/mruby/blob/master/include/mruby.h
// line 915
printf("From the C side, add_c arguments are: %lld, %lld\n", a, b);
return mrb_fixnum_value((mrb_int)(a + b));
}
puts "From the mRuby side, does AModule respond to :add ? -> #{AModule.respond_to?(:add) ? 'yes' : 'no'}"
puts "From the mRuby side, :add call result: #{AModule::add(1, 2)}"
CC=gcc
CFLAGS=-std=c99 -lm
MRUBY_INCLUDE=../../mruby-3.1.0/include
MRUBY_LIB=../../mruby-3.1.0/build/host/lib/libmruby.a
SOURCE=c_from_ruby
all:
$(CC) $(CFLAGS) -I$(MRUBY_INCLUDE) $(SOURCE).c -o $(SOURCE) $(MRUBY_LIB)
clean:
rm -f $(SOURCE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment