Вернуть указатель класса на lua с помощью luabind

Есть ли способ вернуть в функции C ++ указатель на класс в lua? Я пробовал это, среди других более отчаянных вещей:

P* GetP()
{
    return g_P;
}

module(L)
[
    def("GetP", &GetP)
]

Это приводит к сбою программы даже до запуска первой строки в main (), даже если код просто находится в функции, которая никогда не вызывается.

Я думал, что проблема в том, что P неизвестен luabind, но даже сказать ему, что это было не удалось.

module(L)
[
    class_<P>("ClassP")
    .def(constructor<>())
]

Это может быть связано с тем, что у P довольно сложная иерархия наследования, не уверен.

class GO;
class L;
class C : public GO;
class P : public C, L;

Я пробовал разные подходы, чтобы сообщить luabind о наследовании P, ни один из них не дал никакого результата.

Сбой, который я получаю, представляет собой необработанное исключение по адресу 0x0059a064 в program.exe: 0xC0000005: место чтения нарушения прав доступа 0x00000004, обнаруженное в xtree.

_Pairib insert(const value_type& _Val)
    {   // try to insert node with value _Val
        _Nodeptr _Trynode = _Root();
        _Nodeptr _Wherenode = _Myhead;
        bool _Addleft = true;   // add to left of head if tree empty

Любая помощь приветствуется.


person user2359156    schedule 07.05.2013    source источник


Ответы (1)


Зачем вам нужен указатель класса в коде lua? Как класс C ++ он будет непрозрачным ... или, лучше сказать. ~ улыбка ~

Возможно, настроить std :: map в коде C ++ и сохранить указатель на карте с хеш-значением и передать хеш-значение в lua? Затем lua может использовать это для передачи кода C ++ в другом месте.

РЕДАКТИРОВАТЬ: Вы можете немного разыменовать P и передать хеш вместо this в P.

Имейте в виду, что thing:Method() - это просто сокращение для thing.Method( thing ), поэтому использование хеша для thing по-прежнему в значительной степени та же конструкция, но выглядит немного менее объектно-ориентированной.

Что-то подобное сработает ...

std::map<unsigned,P*> p_Map;

void p_AddValue( unsigned hash, int aValue )
{
    if( p_Map.find( hash ) != p_Map.end() )
        p_Map[hash]->AddValue( aValue );
}

unsigned p_New()
{
    P* p = new P();
    unsigned hash;

    do hash = GenerateHash( p );
    while( p_Map.find( hash ) != p_Map.end() );

    p_Map[hash] = p;

    return hash;
}

module(L)
[
    def("p_AddValue", &p_AddValue)
    def("p_New", &p_New)
]

Тогда в Lua вы сможете делать такие вещи ...

local p1 = p_New();
local p2 = p_New();

p_AddValue( p1, 5 );
p_AddValue( p2, 10 );

и т.п.

Это не идеальное решение, но оно должно помочь вам решить возникшую проблему. Надеюсь, кто-то еще может дать лучший ответ?

ПОВТОРНОЕ РЕДАКТИРОВАНИЕ: если подумать, хотя это немного громоздко, может быть другой способ, который позволил бы вам использовать класс P (косвенно) через прокси-класс в Lua ...

class PProxy
{
    protected:

       P  p;

    public:

       PProxy() : P() {};
       ~PProxy() {};

       void AddValue( int aValue ) { p.AddValue( aValue ); }
}

module(L)
[
    class_<PProxy>("P")
    .def(constructor<>())
    .def("AddValue", &PProxy::AddValue)
]
person K Scott Piel    schedule 07.05.2013
comment
Итак, если я вас правильно понял, вы предлагаете мне создать еще один уровень абстракции между P и lua? Например, вместо того, чтобы предоставлять методы класса lua, я взаимодействую с ним примерно так: [Блок 1] Вместо: [Блок 2] Вздох, у меня не работают теги ‹code›, поэтому я использовал pastebin : pastebin.com/sT3SBX6U - person user2359156; 08.05.2013
comment
Ваши правки действительно помогли прояснить это, в итоге я сделал что-то вроде хеш-решения. Но я думаю, что могу в конечном итоге заменить его на прокси-решение, если у меня когда-нибудь появится время вернуться к нему. Не совсем тот ответ, который я искал / надеялся, но он решает мою проблему. Спасибо за уделенное время. - person user2359156; 10.05.2013