Зарегистрировать функцию C ++ в Lua? - PullRequest
1 голос
/ 11 ноября 2011

Я пытаюсь зарегистрировать функцию c ++ в Lua.

Но получаю эту ошибку:

CScript.cpp|39|error: argument of type 'int (CScript::)(lua_State*)' does not match 'int (*)(lua_State*)'|

EDIT:

int CApp::SetDisplayMode(int Width, int Height, int Depth)
{
    this->Screen_Width = Width;
    this->Screen_Height = Height;
    this->Screen_Depth = Depth;

    return 0;
}

int CScript::Lua_SetDisplayMode(lua_State* L)
{
  // We need at least one parameter
  int n = lua_gettop(L);
  if(n < 0)
  {
    lua_pushstring(L, "Not enough parameter.");
    lua_error(L);
  }

  int width = lua_tointeger(L, 1);
  int height = lua_tointeger(L, 2);
  int depth = lua_tointeger(L, 3);

  lua_pushinteger(L, App->SetDisplayMode(width, height, depth));

  return 0;
}

А в основном:

lua_register(L, "setDisplayMode", Lua_SetDisplayMode);

Ответы [ 4 ]

7 голосов
/ 11 ноября 2011

Вы не можете использовать метод класса как нормальную функцию, если он не объявлен static.Вы должны определить нормальную функцию, которая узнает, из какого объекта вы хотите вызвать метод, а затем вызвать метод.

Основная причина, по которой невозможно использовать метод класса в качестве обратного вызова изФункция C (и помните, что Lua API - это чистая библиотека C) связана с тем, что компьютер не знает, к какому объекту должен вызываться метод.

4 голосов
/ 24 января 2014

Ответ на самом деле удивительно прост; если вы используете lua_pushcclosure вместо lua_pushcfunction, вы можете передать параметры в вызываемую функцию:

    lua_pushlightuserdata(_state, this);
    lua_pushcclosure(_state, &MyClass::lua_static_helper, 1);

    int MyClass::lua_static_helper(lua_State *state) {
        MyClass *klass = (MyClass *) lua_touserdata(state, lua_upvalueindex(1));
        return klass->lua_member_method(state);
    }
1 голос
/ 11 ноября 2011

Вы не можете напрямую зарегистрировать нестатическую функцию-член C ++ в Lua, используя только базовый API-интерфейс Lua C.

Тем не менее, существует любой из различных механизмов, позволяющих легко ассоциировать код C ++.с Луа позволит вам сделать это. toLua ++ , SWIG , Luabind и т. Д. Если вы серьезно относитесь к использованию объектов C ++ с Lua, я предлагаю выбрать один из них и использовать его, а ненаписание собственной версии.Я лично использую Luabind (большую часть времени; SWIG занимает свое место в наборе инструментов), так как он не имеет какой-либо формы генерации кода.Все это сделано исключительно в C ++, поэтому нет никакого предварительного этапа, который генерирует исходный файл C ++.

0 голосов
/ 11 ноября 2011

Вы можете обойти ограничение, сохранив активный указатель this в статической переменной.Это создает проблему невозможности одновременной работы двух этих классов, но это работает.

static CScript* luaThis; // This is a private variable inside CScript.

Затем внутри вашего CScript конструктора (или какой-то функции 'activate'), вы можете просто указать:

luaThis = this;

Затем, когда ваши статические функции вызываются (они могут даже быть частными функциями, если они зарегистрированы внутри класса), у вас есть доступ ко всей информации вашего члена черезluaThis указатель.

lua_pushinteger(L, luaThis->App->SetDisplayMode(width, height, depth));

Проблема, как я уже сказал, заключается в том, что это ограничивает вас одним активным CScript за раз (поскольку другой обратный вызов из другого состояния Lua будет использовать luaThis, пока он указываетк неправильным вещам).Если вам когда-либо понадобится несколько активных экземпляров, вы можете придумать какой-нибудь механизм поиска, использующий входящий lua_State* в качестве ключа.

std::map<lua_State*, CScript*> lookups; // Just an idea, if it comes to this.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...