Register C++ function in Lua?

后端 未结 4 1040
小蘑菇
小蘑菇 2021-01-07 07:39

I am trying to register a c++ function in Lua.

But getting this error:

CScript.cpp|39|error: argument of type \'int (CScript::)(lua_State*)\' does n         


        
相关标签:
4条回答
  • 2021-01-07 08:03

    You cannot directly register a C++ non-static member function in Lua using just the basic Lua C API.

    However, any of the various mechanisms that exist for easily associating C++ code with Lua will allow you to do so. toLua++, SWIG, Luabind, etc. If you're serious about using C++ objects with Lua, I suggest picking one of those and using it, rather than writing your own version. I personally use Luabind (most of the time; SWIG has its place in the toolbox), as it is the one that doesn't have some form of code generation. It's all done purely in C++, so there's no pre-pass step that generates a C++ source file.

    0 讨论(0)
  • 2021-01-07 08:09

    The answer is actually surprisingly simple; if you use lua_pushcclosure instead of lua_pushcfunction, you can pass parameters to your called function:

        lua_pushlightuserdata(_state, this);
        lua_pushcclosure(_state, &MyClass::lua_static_helper, 1);
    
        int MyClass::lua_static_helper(lua_State *state) {
            MyClass *klass = (MyClass *) lua_touserdata(state, lua_upvalueindex(1));
            return klass->lua_member_method(state);
        }
    
    0 讨论(0)
  • 2021-01-07 08:23

    You can not use a method of a class as a normal function, unless it is declared static. You have to define a normal function, which finds out what object you want the method to be called in, and then call the method.

    The main reason it's not possible to use a class method as a callback from a C function (and remember that the Lua API is a pure C library), is because the computer doesn't know which object the method should be called on.

    0 讨论(0)
  • 2021-01-07 08:28

    You can work around the limitation by storing your active this pointer in a static variable as well. This introduces the problem of being unable to have two of these classes operating at the same time, but it works.

    static CScript* luaThis; // This is a private variable inside CScript.
    

    Then, inside your CScript constructor (or some kind of 'activate' function), you can just specify:

    luaThis = this;
    

    Then, when your static functions are called (they can even be private functions if they are registered from within the class), you have access to all your member information via the luaThis pointer.

    lua_pushinteger(L, luaThis->App->SetDisplayMode(width, height, depth));
    

    The problem, as I said, is that this restricts you to one active CScript at a time (since another callback from another Lua state would use luaThis while it is pointing to the wrong things). If you need multiple active instances ever, you can come up with some lookup mechanism using the incoming lua_State* as a key.

    std::map<lua_State*, CScript*> lookups; // Just an idea, if it comes to this.
    

    Hope that helps!

    0 讨论(0)
提交回复
热议问题