【问题标题】:reading the 'return' value of mruby program via C在 C 中读取 ruby​​ 程序的“返回”值
【发布时间】:2015-08-25 02:25:59
【问题描述】:

我遇到了在 C 中调用 mruby VM 的问题。我可以调用 mruby vm 并从 C 执行 ruby​​ 代码。我也可以触发 ruby​​ 代码中定义的方法。但是我在尝试读取 ruby​​ 方法的返回值时遇到了问题。我在下面提供了我的示例场景。

代码:

#include <stdlib.h>
#include <stdio.h>

#include <mruby.h>
#include <mruby/compile.h>

int main(void)
{
  mrb_state *mrb = mrb_open();
  char code[] = "def helloworld() return'OK' end";
  printf("Executing Ruby code from C!\n");

  mrb_load_string(mrb, code);
  mrb_load_string(mrb, "helloworld()");
  // How to read the return value?
  return 0;
}

我不确定这是否是调用 ruby​​ 方法的正确方法?我在网上找不到任何文档或示例。任何尝试通过 c(使用 mruby)调用 ruby​​ 代码的人可以帮帮我吗?

问候,

【问题讨论】:

    标签: c mruby


    【解决方案1】:

    mrb_load_string() 的返回值是最后计算的表达式的值。但它也是mrb_undef_value() 在解析或代码生成期间发生的失败,如语法错误。一般来说,如果有未捕获的异常,mrb_stateexc 成员是非空的:

    mrb_value rv = mrb_load_string(mrb, "helloworld()");
    if (mrb->exc) {            // if uncaught exception …
       if (!mrb_undef_p(rv)) { // … during execution/run-time
         mrb_print_error(mrb); // write backtrace and other details to stderr
       }
    }
    else {
      mrb_p(mrb, rv); // similar to Kernel#p
    }
    

    如果你只想调用一个方法,可以使用mrb_funcall()系列函数:

    mrb_value rv = mrb_funcall(mrb, mrb_top_self(mrb), "helloworld", 0);
    

    或者:

    mrb_value rv = mrb_funcall_argv(mrb, mrb_top_self(mrb), mrb_intern_cstr(mrb, "helloworld"), 0, NULL);
    

    然后不会使用解析器和代码生成器,因此它会更快,除非它们在其他地方使用,否则可执行文件或(共享)库也会小得多。加上mrb_undef_value() 不是可能的返回值,否则检查未捕获的异常并检索返回值可以以相同的方式完成。

    【讨论】:

    • ,我尝试了 mrb_funcall 但我不知道如何传递参数。 mrb_funcall 也对我不起作用。你能给我一个例子,它可以调用'helloworld'并传递一个参数(例如:'test',123)并读取返回值吗?这是我的要求。也感谢代码 sn-p 和解释。
    • @programmer: mrb_funcall(mrb, mrb_top_self(mrb), "helloworld", 2, mrb_str_new_cstr(mrb, "test"), mrb_fixnum_value(123));
    • 谢谢,以及如何读取返回值(这里来自 ruby​​,我返回“OK”)。
    • @programmer:与mrb_load_string() 相同(mrb_undef_value() 部分除外,因为它不使用解析器/代码生成器)。我会编辑帖子。
    • 谢谢!这个 mrb_p(mrb, rv);确实打印了返回值“OK”。还有一件事,如何将 rv 值设为 char* 或 (std::string in C++)?这对我有好处! :)。另外如果我使用:mrb_funcall_argv,你能和我分享一个关于如何传递一些输入的例子吗(比如我的 ruby​​ 代码是这样的:def helloworld(var1, var2) ... 其中 var1 是一个字符串,var 2 是一个整数) ?
    猜你喜欢
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    相关资源
    最近更新 更多