how to callback a lua function from a c function

后端 未结 2 826
孤街浪徒
孤街浪徒 2021-02-14 01:52

I have a C function (A) test_callback accepting a pointer to a function(B) as the parameter and A will \"callback\" B.

//typedef int(*data_callback         


        
2条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-14 02:31

    The convenient way of doing calls to different Lua functions with different signatures:

    A. Make a class that will maintain Lua state safely and will provide easy interface. Do not write calls to Lua functions from scratch (with a lot of push/pop work and asserts) again and again - just use this class interface. This is safe, fast and convenient approach.

    B. Define push and pop methods to push/pop arguments on/from Lua stack:

    template void push(T argument);
    template void get(const int index, T& return_value);
    
    template<> void State::push(bool arg)
    {
      lua_pushboolean (lua_state, arg ? 1 : 0);
    }
    
    template<> void State::push(float arg)
    {
      lua_pushnumber (lua_state, arg);
    }
    
    template<> void State::push(int arg)
    {
      lua_pushnumber (lua_state, arg);
    }
    
    // ...
    template<> void State::get(const int index, bool& ret)
    {
          if (!lua_isboolean(lua_state, index)) { ... }
          ret = lua_toboolean(lua_state, index) != 0;
    }
    

    C. Define functions to call Lua functions:

    // Call function that takes 1 argument and returns nothing
    template 
    void call(const char * funcName, A1 arg1)
    {
      lua_getfield (lua_state, LUA_GLOBALSINDEX, funcName);       // push global function f on stack
      push (arg1);                                            // push first argument on stack
      assert_call(    lua_pcall(lua_state, 1, 0, this->err_h) );      // call function taking 1 argument and getting no return value
    }
    
    
    // call function that takes 2 argument and returns 1 value
    template 
    void callr1(const char * funcName, R1& res, A1 arg1, A2 arg2)
    {
      lua_getfield (lua_state, LUA_GLOBALSINDEX, funcName);       // push global function f on stack
      push (arg1);                                            // push first argument on stack
      push (arg2);
      assert_call(    lua_pcall(lua_state, 2, 1, this->err_h) );      // call function taking 2 arguments and getting 1 return value
      get  (-1, res);
      lua_pop(lua_state, 1);
    }
    

    D. Set error handler (lua_pcall will call this Lua function if error)

    void setErrorHandler(const char * funcName)
    {
      lua_getfield (lua_state, LUA_GLOBALSINDEX, funcName);
      this->err_h = lua_gettop(lua_state);
    }
    

提交回复
热议问题