Функция ожидает объект C ++ абстрактного типа A. Как передать ему объект Lua подкласса A? - PullRequest
4 голосов
/ 29 апреля 2009

Я хотел бы передать функции, ожидающей объект C ++ чисто виртуального класса, объект Lua класса, производного от чисто виртуального класса C ++. Как я могу это сделать?

Я новичок в Луа и Луабинде, так что терпите меня.

В C ++:

struct A {
  virtual void foo() = 0;
};

void do_something(A* a) {
  a->foo();
}

В Lua:

class 'MyA' (A)
....
function MyA:foo()
  print('hi')
end

В C ++ снова:

... // somehow create an instance of MyA class and named myA
    // How? 
    // Maybe the result of a call to "MyA()"?

do_something(myA);

Ответы [ 4 ]

2 голосов
/ 30 апреля 2009

См. Раздел 10.1 в документации LuaBind. В основном вы предоставляете простую оболочку C ++ для класса LuaBind, которая действует как проход к базовой реализации Lua. Обратите внимание на следующее из этого документа:

virtual void f(int a) 
{ 
    call<void>("f", a); 
}

вызов ("f", a) вызовет функцию Lua 'f', передав аргумент a.

2 голосов
/ 30 апреля 2009

Извините, я бы не стал отвечать на вопрос, который вы задали напрямую, но вместо этого предложил бы небольшой совет из личного опыта:

Если вы новичок для Lua, вам следует серьезно подумать о написании ваших первых привязок в raw Lua API и без такой объектно-ориентированной компоновки. По крайней мере, вы поймете, что в действительности происходит .

Lua API довольно удобен для использования сам по себе. Это не создает лишних накладных расходов, и вы полностью контролируете происходящее. Разработка библиотеки Luabind в настоящее время немного устарела (но, похоже, она возвращается к жизни).

Вы должны учитывать, действительно ли вам необходимо имитировать производные от классов C ++ на стороне Lua и, особенно, на стороне C ++. Такая вещь не так уж естественна для Lua и требует заметных накладных расходов для реализации. Кроме того, в C ++ вы скрываете тот факт, что вы делаете не нативный вызов другого языка. Если это не задокументировано, это потенциальный источник проблем с производительностью.

Когда я начал работать с Lua несколько лет назад, я привык писать привязки так же, как вы, с Luabind, и имитировать производные от объектов C ++. Сейчас я использую чистый Lua API и упрощенный процедурный (в отличие от объектно-ориентированного) кросс-языковой интерфейс. Я очень доволен результатом.

2 голосов
/ 30 апреля 2009

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

Базовый псевдокод:

// C++
struct LuaA : public A
{
  LuaA(const std::string &luacode)
    : myLuaHandler(luacode)
  {
  }

  virtual void foo()
  {
    myLuaHandler.call("MyA:foo()");
  }
}

Этот пример очень высокого уровня, но он призван показать, что то, что вы хотите сделать, нетривиально. Это новый "LuaA", который вы бы хотели использовать в своем коде Lua.

В целом, я предпочитаю использовать SWIG при упаковке C ++ для ознакомления с Lua и другими скриптовыми языками. SWIG поддерживает эту перегрузку интересующих вас виртуальных методов (называемых на языке SWIG «директорами»), однако следует отметить, что Lua / SWIG не поддерживает директоров. Java, C #, Ruby, Perl и Python имеют поддержку директоров в SWIG. Я не знаю точно, почему это не поддерживается в Lua.

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

Возможно, у кого-то есть лучший ответ на Lua?

1 голос
/ 30 апреля 2009

Я сделаю подкласс чистого виртуального класса в C ++, а затем, вероятно, начну с luabind (согласно решениям Аарона и Лефтикуса). Если эти издержки слишком велики, я просто воспользуюсь прямым API-интерфейсом стека Lua C. (согласно Александру).

Таким образом, здесь нет одного ответа. Я опубликую комментарии с результатами позже.

Спасибо всем!

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