mruby-porting/src/05mrbgems/Makefile
3. GEM終了関数の定義
68 Copyright(C) 2018 mruby Forum, SCSK KYUSHU CORP.
Cによるmruby VMの拡張
Cによるmruby VMの拡張
mruby-porting/src/06mrbgem2/sample-mrbgem/src/neg.c
#include "mruby.h"
#include "mruby/value.h"
static mrb_value neg(mrb_state *mrb, mrb_value self) {
return mrb_fixnum_value(-mrb_fixnum(self));
}
void mrb_sample_mrbgem_gem_init(mrb_state *mrb) {
mrb_define_method(mrb, mrb->fixnum_class, "negative", neg, MRB_ARGS_NONE());
}
void mrb_sample_mrbgem_gem_final(mrb_state *mrb) {
}
mruby
から呼び出すC
言語関数GEM
終了関数(mrb_XXX_gem_final) GEM
初期化関数(mrb_XXX_gem_init)
C
の関数neg()
をmruby
のメソッド(Fixnum
クラスのnegative
メソッド)
として登録mrbgem
名に合わせるmrbgem
名に合わせるmrbgem
名に合わせるmrubyから呼び出し可能なC関数の形式
関数型
mrb_value func(mrb_state *mrb, mrb_value self);
引数
mrb mrb_state
のポインタが渡される。self
メソッドのレシーバが渡される。戻り値 メソッドの処理結果である戻り値を
mrb_value
型にて返却する。(値は処理に依存)
メソッドの機能として戻り値を返す必要がない場合も、何らかの
mrb_value
値を返す必要がある。機能概要
mruby
プログラムから呼び出されるC
関数は、本関数と同じ形式である必要がある。
C
関数に渡される引数は、C
関数内でmrb_get_args()
を呼び出すこと で取得することができる。備考 関数名
(func)
は任意の関数名を指定可能。メソッドの登録 (mrb_define_method)
関数型
void mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_c func, int aspec);
引数
mrb mrb_state
のポインタが渡される。c
メソッドの登録対象となるクラス/モジュールの オブジェクトを指定する。name mruby
プログラムから呼び出す際のメソッド名を指定する。
func
呼び出し対象のC
言語関数を指定する。呼び出される
C
関数は、以下の関数型である必要がある。mrb_value func(mrb_state*, mrb_value);
aspec
メソッドが受け取る引数を指定する。(
次頁参照)
戻り値 なしmrb_define_methodのaspecに指定するマクロ
MRB_ARGS_NONE()
引数なしfoo()
MRB_ARGS_REQ(n) n個の必須の引数を持つ
foo(a, b, c) # => MRB_ARGS_REQ(3) MRB_ARGS_OPT(o) o個のオプション引数を持つ
foo(a=1, b=nil) # => MRB_ARGS_OPT(2) MRB_ARGS_ANY()
可変数の引数を持つfoo(*args)
MRB_ARGS_ARG(n, o) n個の必須引数、o個のオプション引数を持つ ARGS_REQ(n) | ARGS_OPT(o) と同じ
foo(a, b, c=1) # => MRB_ARGS_ARG(2, 1)
mrb_valueを生成するAPI
mrb_fixnum_value(i)
整数型のmrb_valueを生成する。mrb_float_value(mrb, f)
浮動小数値のmrb_valueを生成する。mrb_symbol_value(i)
シンボル値のmrb_valueを生成する。mrb_obj_value(p)
オブジェクトの実体pを持つmrb_valueを生成 する。mrb_false_value() false値のmrb_valueを生成する。
mrb_true_value() true値のmrb_valueを生成する。
mrb_bool_value(boolean)
真偽値(true/false)のmrb_valueを生成する。mrb_nil_value() nil値のmrb_valueを生成する。
mrb_valueから値を取得するAPI
mrb_fixnum(v) mrb_valueの整数値を取得する。
(v).value.i
mrb_float(v) mrb_valueの浮動小数値を取得する。
(v).value.f
mrb_symbol(v) mrb_valueのシンボル値を取得する。
(v).value.sym
mrb_ptr(v) mrb_valueのオブジェクトポインタを取得する。
(v).value.p
mruby-porting/src/06mrbgem2/build_config_sample_mrbgem.rb
mrbgemの組み込み
MRuby::Build.new do |conf|
conf.gem '../../src/06mrbgem2/sample-mrbgem'
end
相対パスで指定する場合にはmruby/mrbgems
基準の パスとなる$ cd /c/mruby-porting/src/06mrbgem2
$ make
$ ../../mruby/bin/mirb
> 100.square.negative
Mac
の場合はcd ~/mruby-porting
動作確認
作成するmrbgem
mruby-porting/src/07practice1/banker
Cで実装するもの
Bankerクラス
Banker#counter(n=2) メソッド n: 倍数 (デフォルト: 2)
nが2の場合: "倍返しだ!" の文字列を返す
nが2以外の場合: "#{n}
倍返しだ!"
の文字列を返すmrbgem (banker) の作成
実行例
$ cd /c/mruby-porting/src/07practice1
$ make
$ ../../mruby/bin/mirb
> hnzw = Banker.new
=> #<Banker:0x7fde3f001b70>
> hnzw.counter(2) => 倍返しだ!
> hnzw.counter(100) => 100倍返しだ!
>
Mac
の場合はcd ~/mruby-porting
クラスの登録 (mrb_define_class)
関数型
struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super);
引数
mrb mrb_state
のポインタを指定する。name
クラスの名称を指定する。super
親クラスのクラスオブジェクトを指定する。戻り値 定義されたクラスオブジェクトのポインタを返す。
機能概要 クラスを定義する。
備考
super
には、以下に示すmrb_state
構造体内に保持されている既存のクラスを指定することが可能。
mrb->object_class
オブジェクトクラスmrb->array_class Array
クラスmrb->string_class String
クラス引数の取得 (mrb_get_args)
関数型
int mrb_get_args(mrb_state *mrb, const char *format, ...);
引数
mrb mrb_state
のポインタを指定する。format
次頁に示す文字で取得する引数の型を指定する。(複数指定可能)
... format
で指定した可変数引数の値を受け取る変数のポインタを指定する。
戻り値 取得した引数の数を返す。
機能概要 メソッドに渡された引数を取得する。
備考
mrb_get_argsのformat指定文字列とデータ型
format
取得する引数 引数を受け取る変数型o
オブジェクト(Object)mrb_value S
文字列(String)mrb_value s
文字列と文字長char *, int z
文字列(終端が'¥0')char *
A
配列(Array)mrb_value
a
配列と配列長mrb_value *, int f
浮動小数値mrb_float
i
整数値mrb_int
n
シンボル値mrb_sym
b
真偽値mrb_bool
&
ブロックmrb_value
*
残りの引数と引数の数mrb_value *, int
|
後続はオプション引数-
文字列の生成 (mrb_str_new_cstr)
関数型
mrb_value mrb_str_new_cstr(mrb_state *mrb, const char *p);
引数
mrb mrb_state
のポインタを指定する。p
文字列('¥0'
終端)
を指定する。戻り値
String
オブジェクトを返す。機能概要
C
言語文字列よりString
オブジェクトクラスを生成する。Rubyで str = "C_STR" を実行することと等価。
備考
ヒント:クラス定義の例
#include "mruby.h"
#include "mruby/value.h"
#include <stdio.h>
static mrb_value
surprise(mrb_state *mrb, mrb_value self) {
mrb_int n, i;
mrb_value s = mrb_str_buf_new(mrb, 32);
mrb_get_args(mrb, "i", &n);
for (i=0; i<n; i++) mrb_str_cat_cstr(mrb, s, "じぇ");
return s;
}
void
mrb_ama_gem_init(mrb_state *mrb) {
struct RClass *ama = mrb_define_class(mrb, "Ama", mrb->object_class);
mrb_define_method(mrb, ama, "!", surprise, MRB_ARGS_REQ(1));
}
Ama
クラスを定義(親クラスは
Object
クラス)数値を文字列に変換するには sprintf() 関数を使用します。
使用例
ヒント:数値の文字列化
#include <stdio.h>
int main(void) {
char buf[16];
int i;
for (i=0; i<10; i++) {
sprintf(buf, "%d回目", i);
puts(buf);
} }
文字列を格納するために十分なサイズの 領域を確保
mrubyのコアは環境依存しない
実行環境用のmruby VMを作成すればOK
アプリケーション (バイナリ) も環境依存しない
開発環境で動作したアプリは他のmruby VMでも動作可能
カスタマイズ可能なmruby VM 実行環境に合わせてチューニング
移植性の高いmruby
mrubyのクロスビルド
ターゲット環境 (実行環境) 用のmruby VMを作成
mrubyのカスタマイズ
mruby VMの構成、mrbgemの追加/削除
ターゲットアプリケーションへのmruby VMの組み込み アプリケーションからmruby APIを呼び出す
mrubyのポーティング手順(概要)
mrubyアプリ実行形式の決定材料
実行形式
RAM
容量(
目安) ○ ×
スクリプト
512KB
〜•
実行が容易•
アプリ更新も容易•
コンパイルにメモリ と時間が必要•
スクリプトが丸見えMRB
ファイル192KB
〜• MRB
ファイルの差し替えでアプリを 更新できる
•
ファイルシステムが 必須バイナリデータ
(C
ソース) 128KB
〜•
サイズがコンパクト
•
アプリのみの更新が 難しい mrubyでターゲットシステムを動かす
ターゲット依存するCモジュールの呼び出しOSのシステムコール、I/O制御処理など...
Cモジュール呼び出し部のライブラリ(mrbgem)化
Cの資産をmrubyの資産に!
mrubyのポーティング後に必要なこと
MPU: RZ/A1H (Cortex-A9) 400MHz
Flash: 8MB
ドキュメント内
Mruby基本研修
(ページ 68-90)