Добавление функции-члена в класс C ++, связанный с Lua - PullRequest
4 голосов
/ 02 декабря 2011

Я работал над тем, как связать классы 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 ]

0 голосов
/ 06 мая 2012

Я думаю Я понимаю вопрос и могу иметь представление о решении.Технически нет связи между классом lua Monster и классом C ++ Monster.Когда вы вызываете lua «функцию-член» для данного объекта lua, он не знает о конкретном объекте Monster в C ++.Если вы хотите вызвать нестатический метод объекта C ++, вы не можете использовать C-функцию lua для этого.Вам нужно было бы где-то привязать пользовательские данные к вашему объекту lua, который имеет указатель на объект C ++ (будьте очень осторожны с временем жизни объекта - вы должны использовать полные пользовательские данные и переопределить __gc в lua с помощью C-функции, которая уничтожаетобъект C ++).В этом случае вы можете объявить закрытый статический метод C ++ в классе Monster, который ожидает эти пользовательские данные, а затем преобразует указатель и вызывает нестатическую функцию-член для этого конкретного объекта C ++ monster с заданными аргументами.(Надеюсь, я понимаю ваш вопрос, и что мой ответ написан достаточно четко.)

0 голосов
/ 03 января 2013

Когда вы пишете

function Monster:pounce(howhigh, bonus)

это ярлык для

Monster.pounce = function(self, howhigh, bonus)

Так очевидно, что это называется

Monster.pounce(badguy, 5, 1);

как и ты, имеет смысл.

Но вы хотите сделать что-то другое: из вашего модуля C ++ вы получите таблицу с именем Monster. Вы не хотите манипулировать самой таблицей, поскольку она (только?) Содержит запись с именем create, конструктором monster.

Я должен признать, что я не полностью получаю код, к которому вы привязаны, но, предполагая, что метод монстра доступен из метатаблицы, вы можете вставить метод pounce в этот метатабль.

0 голосов
/ 02 декабря 2011

невозможно вызвать ваш 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

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

...