Question

Is there any way that I can, in a C++ function, return a pointer to a class to lua? I have tried this, among other more desperate things:

P* GetP()
{
    return g_P;
}

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

This makes the program crash even before running the first line in main(), even if the code just sits in a function that is never called.

I thought it was a problem that P was unknown to luabind, but even telling it what it was failed.

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

This could be because P have a somewhat complex inheritance hierarchy, not sure.

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

I have tried different approaches to tell luabind of the inheritance of P, none gave any result.

The crash I get is a Unhandled exception at 0x0059a064 in program.exe: 0xC0000005: Access violation reading location 0x00000004, found in 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

Any help appreciated.

Was it helpful?

Solution

Why do you want the class pointer in the lua code? As a C++ class, it's going to be opaque... or better be. ~smile~

Perhaps set up a std::map in the C++ code and store the pointer in the map with a hash value and pass the hash value to the lua? The lua can then use that to pass back to the C++ code elsewhere.

EDIT: You could dereference P a bit and pass around a hash as a substitute for the this in P.

Keep in mind that thing:Method() is just a shorthand for thing.Method( thing ) -- so, using a hash for thing is still largely the same construct, but a little less OO in appearance to the eye.

Something similar to this would work...

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)
]

Then in Lua you should be able to do things like this...

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

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

etc.

It's not a perfect solution, but it should get you around the issue you're having. Hopefully someone else maybe can come along with a better answer?

RE-EDIT: come to think of it, though a tad cumbersome, there might be another way that would allow you to use the P class (indirectly) via a proxy class in 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)
]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top