Простейшая функция lua, которая возвращает вектор строк

Мне нужна очень простая функция C++, которая вызывает функцию lua, которая возвращает массив строк и сохраняет их как вектор C++. Функция может выглядеть примерно так:

std::vector<string> call_lua_func(string lua_source_code);

(где исходный код lua содержит функцию lua, которая возвращает массив строк).

Есть идеи?

Спасибо!

3 ответа

Решение

Вот некоторый источник, который может работать для вас. Это может потребовать еще немного полировки и тестирования. Ожидается, что кусок Lua возвращает массив строк, но с небольшими изменениями может вызвать именованную функцию в блоке. Так что, как есть, он работает с "return {'a'}" в качестве параметра, но не "function a() return {'a'} end" в качестве параметра.

extern "C" {
#include "../src/lua.h"
#include "../src/lauxlib.h"
}

std::vector<string> call_lua_func(string lua_source_code)
{
  std::vector<string> list_strings;

  // create a Lua state
  lua_State *L = luaL_newstate();
  lua_settop(L,0);

  // execute the string chunk
  luaL_dostring(L, lua_source_code.c_str());

  // if only one return value, and value is a table
  if(lua_gettop(L) == 1 && lua_istable(L, 1))
  {
    // for each entry in the table
    int len = lua_objlen(L, 1);
    for(int i=1;i <= len; i++)
    {
      // get the entry to stack
      lua_pushinteger(L, i);
      lua_gettable(L, 1);

      // get table entry as string
      const char *s = lua_tostring(L, -1);
      if(s)
      {
        // push the value to the vector
        list_strings.push_back(s);
      }

      // remove entry from stack
      lua_pop(L,1);
    }
  }

  // destroy the Lua state
  lua_close(L);

  return list_strings;
}

Прежде всего, помните, что массивы Lua могут содержать в качестве ключей не только целые числа, но и другие типы.

Затем вы можете импортировать исходный код Lua, используя luaL_loadstring.

На данный момент остается только одно требование - "вектор возврата". Теперь вы можете использовать lua_istable проверить, является ли значение таблицей (массивом) и использовать lua_gettable извлечь несколько полей (см. http://www.lua.org/pil/25.1.html) и вручную добавить их одно за другим в вектор.

Если вы не можете понять, как работать со стеком, то, похоже, вам помогут некоторые учебники. Чтобы узнать количество элементов, я нашел этот пост в списке рассылки, который может быть полезен.

Сейчас у меня не установлен Lua, поэтому я не могу проверить эту информацию. Но я надеюсь, что это все равно поможет.

Не совсем ответ на ваш вопрос:
У меня было много проблем при написании кода на языке C++ <=> lua с простым lua c-api. Затем я протестировал множество разных lua-оболочек и действительно предлагаю luabind, если вы пытаетесь достичь чего-то более или менее сложного. Можно сделать типы доступными для lua за считанные секунды, поддержка умных указателей работает отлично, и (по сравнению с другими проектами) документация более или менее хороша.

Другие вопросы по тегам