Добавление функции-члена в класс C++, связанный с Lua
Я работал над тем, как связать классы C++ с Lua для использования в игровом движке, и столкнулся с интересной проблемой. Я следил за учебником на этом сайте: http://tinyurl.com/d8wdmea. После обучения я понял, что следующий код он предложил:
local badguy = Monster.create();
badguy.pounce = function(self, howhigh, bonus)
self.jumpbonus = bonus or 2;
self:jump(howhigh);
self:rawr();
end
badguy:pounce(5, 1);
Добавит только функцию pounce к этому конкретному экземпляру монстра. Поэтому я изменил предложенный им сценарий следующим образом:
function Monster:pounce(howhigh, bonus)
print("in pounce function");
print(bonus);
self.jumpbonus = bonus or 2
self:jump(howhigh);
self:rawr();
end
local badguy = Monster.create();
badguy:pounce(5,1);
Однако, когда я вызываю функцию pounce, скрипт ломается. После дальнейшего тестирования единственный способ успешно вызвать функцию pounce - это вызвать функцию как статический член класса Monster (код функции остается прежним):
Monster.pounce(badguy,5,1);
Синтаксически, badguy:pounce(5,1) является правильным, но неправильно вызывает функцию. Я просто делаю что-то не так, или это ограничение связывания между lua и C++/ как я связываю два языка?
3 ответа
Когда ты пишешь
function Monster:pounce(howhigh, bonus)
это ярлык для
Monster.pounce = function(self, howhigh, bonus)
Так очевидно, называя это
Monster.pounce(badguy, 5, 1);
как ты и сделал, имеет смысл.
Но вы хотите сделать что-то другое: из вашего модуля C++ вы получите таблицу с именем Monster
, Вы не хотите манипулировать самой таблицей, так как она (только?) Содержит запись с именем create
, monster
конструктор.
Я должен признать, что я не получаю полностью код, к которому вы привязаны, но если предположить, что метод монстра доступен из метатаблицы, вы можете вставить метод pounce
в этой метатабельной.
Я думаю, что я понимаю вопрос, и, возможно, есть представление о решении. Технически нет связи между классом lua Monster и классом C++ Monster. Когда вы вызываете lua "функцию-член" для данного объекта lua, он не знает о конкретном объекте Monster в C++. Если вы хотите вызвать нестатический метод объекта C++, вы не можете использовать lua-функцию C для этого. Вам нужно было бы где-то привязать пользовательские данные к вашему объекту lua, который имеет указатель на объект C++ (будьте очень осторожны с временем жизни объекта - вы должны использовать полные пользовательские данные и переопределить __gc в lua с помощью C-функции, которая уничтожает объект C++). В этом случае вы можете объявить закрытый статический метод C++ в классе Monster, который ожидает эти пользовательские данные, а затем преобразует указатель и вызывает нестатическую функцию-член для этого конкретного объекта C++ monster с заданными аргументами. (Надеюсь, я понимаю ваш вопрос, и что мой ответ написан достаточно четко.)
Невозможно вызвать ваш C-объект / функцию напрямую со всеми ее параметрами. Вы должны зарегистрировать C-функцию в вашем Lua-State. Эта функция должна выглядеть так:
static int myfunc (lua_State *L) {
// your code
return X; /* X = number of results */
}
Эта функция получает только Lua-State в качестве параметра. Все параметры вызова Luafunction лежат в стеке lua. Затем вы должны получить из стека и вызвать с ним ваш метод C++.
Регистрация функции очень проста и выполняется с двумя строками кода:
lua_pushcfunction(l, myfunc);
lua_setglobal(l, "myfuncnameinlua");
Вы можете найти больше информации об этом в этой главе книги " Программирование на языке lua".
То, что вы хотите сделать, реализовать Lua-Object немного сложнее, потому что вы должны зарегистрировать метатаблицу для создания Lua Object, но ваш интерфейс Lua to C все еще является функциями объясненного вида.
Вы также можете использовать Lua-Object в книге Роберто Иерусалимского в главе 28.
Я надеюсь, что это поможет вам