2009-04-29 3 views
4

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

Я новичок в lua и luabind, так что медведь со мной.

В 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); 
+0

Почему этот вопрос был отредактирован? Новый заголовок слишком общий. – z8000

ответ

2

Вы должны создать класс 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?

+0

Это похоже на решение Аарона ниже. Я думаю, что это, вероятно, метод, с которым я поеду. Это утомительно, но это сработает. Благодаря! – z8000

2

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

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

вызова («F», а) будет вызывать функцию Lua «F», передавая в качестве аргумента в.

+0

Да, я пытался избежать этого, потому что это довольно утомительно, но я полагаю, что когда он настроен, я закончил. Хорошо, спасибо! – z8000

2

К сожалению, я не ответил бы на вопрос вы задали непосредственно, но предложу немного советов из личного опыта, а не:

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

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

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

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

+0

Это определенно действительные проблемы. Причина этого вопроса в том, что я уже использую систему на основе классов (Apache Thrift) и хочу реализовать обработчик службы в Lua вместо C++. Я пытался избежать шаблона, где я реализую обработчик сервиса на C++, и его методы по сути просто называют Lua. Я надеялся просто сделать подкласс в Lua себя. Увы, я думаю, что я поеду, по сути, в смесь всех трех решений, опубликованных до сих пор (Александр, Аарон, левый). Спасибо! – z8000

1

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

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

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