mieki256's diary



2018/03/20(火) [n年前の日記]

#1 [ruby][mruby] Cプログラムに組み込んだmruby側のエラー処理

Cで書いたプログラムに組み込んだ mruby 側で、エラーが出ていることを判別したり、どんなエラー内容なのかを取得したり、ということをしたいわけで。

ググったら、やっぱりちゃんと機能として用意されてた。

_Cでmrubyコード実行時に発生したエラーの内容とバックトレースを取得 - Qiita
_Cに組み込んだmrubyのコードのエラーハンドリングについて - Kentaro Kuribayashi's blog

手元のソースでは、以下のような感じにしてみた。mruby 側でエラーが出た時だけ、エラー内容を printf() で出力して、return -2 で戻る処理。

// display mruby state error
void mrb_state_error_disp(mrb_state *mrb)
{
  // error
  mrb_value exc = mrb_obj_value(mrb->exc);

  // error information
  mrb_value backtrace = mrb_get_backtrace(mrb, exc);
  mrb_value inspect_bt = mrb_inspect(mrb, backtrace);
  printf("%s\n", mrb_str_to_cstr(mrb, inspect_bt));

  // backtrace
  enum mrb_vtype type = mrb_type(exc);
  mrb_value inspect = mrb_inspect(mrb, exc);
  printf("%d : %s\n", type, mrb_str_to_cstr(mrb, inspect));
}

...

  mrb_state *mrb = mrb_open();

  fp = fopen("main.rb", "r");
  mrb_obj = mrb_load_file(mrb, fp);
  fclose(fp);

  if (mrb->exc != 0 && (mrb_nil_p(mrb_obj) || mrb_undef_p(mrb_obj)))
  {
    // error
    mrb_state_error_disp(mrb);
    mrb->exc = 0;

    mrb_close(mrb);
    return -2;
  }

mrb_load_file(mrb_state *mrb, FILE *fp) で、mrubyスクリプトファイルを読み込んで実行することができるけど、その時の戻り値を取っておいて…。

mrubyのコードを評価した結果が上記のようなエラーとなった場合、以下の値が帰ってきます。

* コンパイル時のエラー: nil(mrb_nil_value()の返す値)
* 実行時のエラー: undef(mrb_undef_value()の返す値)

また、mrb->excにエラーの内容が代入されます。

Cに組み込んだmrubyのコードのエラーハンドリングについて - Kentaro Kuribayashi's blog より

ということらしいから、以下でエラーが出たかどうかを判別できる。
  if (mrb->exc != 0 && (mrb_nil_p(mrb_obj) || mrb_undef_p(mrb_obj)))
  {
    // error
  }

ちなみに、mruby関係の記事を色々眺めていて、なんだか分かってきたけど、mruby の場合、〜_p とついてる関数だかマクロだかは、「〜な状態か?」を 真/偽 (1/0、TRUE/FALSE) で返すことになっているらしい。

以上です。

過去ログ表示

Prev - 2018/03 - Next
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project