Подтвердить что ты не робот

Вставка интерпретатора Ruby в приложение С++

Я надеюсь использовать Ruby в качестве скриптового языка для моего игрового движка. Я нашел обычные статьи, описывающие, как вызвать классы Ruby из кода на С++ и наоборот (например, здесь), но я не могу понять, как делать то, что я хочу, таким образом работать...

В настоящее время мой движок использует небольшой язык, который я написал себе с помощью Flex и Bison, и небольшую виртуальную машину на основе стека. Скрипты не всегда запускаются прямо от начала до конца, например, иногда они включают в себя такие команды, как "sleep в течение 2 секунд" или "дождитесь окончания символа", поэтому планировщик сохраняет вкладки в состояние каждого script и указатель инструкции и знает, когда их возобновлять, и т.д.

Так кажется, что мне действительно нужен какой-то встроенный интерпретатор Ruby, который я могу осуществлять определенную степень контроля, а не просто вызывать методы Ruby. Или я просто тупой и чего-то не хватает?

Я работаю в Microsoft Visual С++, поэтому в идеале любое решение будет легко компилироваться в этом.

4b9b3361

Ответ 1

Вот пример, включающий обработку ошибок.

#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;
}

Ответ 2

Ты на правильном пути. Ключ состоит в том, чтобы сделать что-то похожее на раздел Embedding Concepts в указанной вами ссылке. Проще говоря, это немного больше:

ruby_init();
ruby_script("some_script");

Возможно, вам понадобится скопировать все #ifdef вещи из main.c, чтобы все работало. С тех пор это вопрос создания API для ваших функций на С++, которые вы хотите открыть, и в зависимости от вашего дизайна, многопоточность.

Ответ 3

Вы всегда можете перепроектировать способ работы сценариев в соответствии с движком script, а не пытаться заставить движок работать с исходными парадигмами сценариев.

Итак, если у вас есть это:

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

который потребовал бы, чтобы script был приостановлен на линии ожидания, выполните следующее:

proc
  action1
  action2
  set timer (time, callback_proc)
end

callback_proc
  action3
end

который позволяет скриптовому механизму полностью очистить каждый метод. Для хостинга не потребуется много изменений - для каждой версии требуется некоторая форма системы событий, которая может перезапустить движок script.

Ответ 4

Существует руководство о том, как вставлять ruby ​​в приложение на С++. Это может быть полезно. В противном случае перейдите в Ruby documentation. Вставить Ruby в C может также оказаться полезной.

Ответ 5

Я думаю, что вам нужно будет использовать Ruby threads. Я проделал честную обработку кода Ruby Threading, и я знаю, что (где доступны pthreads) сон реализуется неблокирующимся способом, используя pthread_cond_timedwait. Это разблокирует интерпретатор, чтобы другие потоки могли продолжить выполнение.

Ваш собственный код должен будет уважать потоки Ruby, когда дело доходит до взаимодействия с интерпретатором Ruby. У них все еще есть глобальная блокировка VM в Ruby, что означает, что вы должны быть осторожны в том, чтобы модифицировать что-либо в интерпретаторе без собственной блокировки.