在C ++应用程序中嵌入Ruby解释器

时间:2009-03-09 13:56:59

标签: c++ ruby scripting

我希望将Ruby用作我的游戏引擎的脚本语言。我找到了通常的文章,描述了如何从C ++代码调用Ruby类,反之亦然(例如here),但我不太明白如何用这种工作方式做我想做的事......

我的引擎目前使用的是我用Flex和Bison编写的一种语言,以及一个基于小堆栈的虚拟机。脚本并不总是从头到尾运行,例如它们有时包括“睡2秒”或“等到角色走完”等命令,因此调度程序会密切关注每个脚本的状态和指令指针,并知道何时恢复它们,等等。

所以我似乎真的需要某种嵌入式Ruby解释器,我可以对它进行一定程度的控制,而不是简单地调用Ruby方法。或者我只是迟钝而错过了什么?

我正在使用Microsoft Visual C ++,所以理想情况下,任何解决方案都可以轻松编译。

5 个答案:

答案 0 :(得分:29)

这是一个包含错误处理的例子。

#include <iostream>
#include <ruby.h>

using namespace std;

int main(void)
{
  ruby_init();
  ruby_init_loadpath();
  int status;
  rb_load_protect(rb_str_new2("./test.rb"), 0, &status);
  if (status) {
    VALUE rbError = rb_funcall(rb_gv_get("$!"), rb_intern("message"), 0);
    cerr << StringValuePtr(rbError) << endl;
  };
  ruby_finalize();
  return status;
}

答案 1 :(得分:4)

你走在正确的轨道上。关键是要做一些类似于您发布的链接中Embedding Concepts部分的内容。简单来说,它只不过是:

ruby_init();
ruby_script("some_script");

您可能需要复制main.c中的所有#ifdef内容以使所有内容正常运行。从那时起,您需要为要公开的C ++函数构建API,并根据您的设计,多线程化。

答案 2 :(得分:4)

您可以随时重新设计脚本的工作方式以适应脚本引擎,而不是试图让引擎与原始脚本范例一起使用。

所以,如果你有这个:

proc:
  action 1
  action 2
  sleep a bit
  action 3
end

这将要求脚本在睡眠线上暂停,请执行以下操作:

proc
  action1
  action2
  set timer (time, callback_proc)
end

callback_proc
  action3
end

让脚本引擎整齐地完成每个方法。它不需要对主机端进行很多更改 - 每个版本都需要某种形式的事件系统来重启脚本引擎。

答案 3 :(得分:3)

关于如何将ruby嵌入到C ++应用程序中有一个guide。这可能会有所帮助。否则请转到Ruby documentationEmbed Ruby in C文章也可能会有所帮助。

答案 4 :(得分:1)

我认为你想要做的是使用Ruby的线程。我已经完成了一些挖掘Ruby线程代码的工作,我知道(pthreads可用的地方)sleep是使用pthread_cond_timedwait以非阻塞方式实现的。这会解除对解释器的阻塞,以便其他线程可以继续执行。

在与Ruby解释器交互时,您自己的代码必须尊重Ruby的线程。他们仍然使用Ruby中的全局虚拟机锁定,这意味着你应该小心修改解释器中的任何内容,而无需自己锁定。