如何让 lua 调用将 returns 多个值赋给 lua 的 c++ 函数

how to have lua call a c++ function that returns multiple values to lua

我的代码(部分) C++:

lua_register(L, "GetPosition", lua_GetPosition);

int lua_GetPosition(lua_State* L)
{
    Entity e = static_cast<Entity>(lua_tointeger(L, 1));
    TransformComponent* trans = TransformComponentPool.GetComponentByEntity(e);
    if (trans != nullptr)
    {
        lua_pushnumber(L, trans->transform->position.x);
        lua_pushnumber(L, trans->transform->position.y);
        lua_pushnumber(L, trans->transform->position.z);
    }
    else
    {
        lua_pushnumber(L, 0);
        lua_pushnumber(L,0);
        lua_pushnumber(L, 0);
        LOG_ERROR("Transform not found");
    }
    return 1;
}

lua:

local x = 69
local y = 69
local z = 69
x,y,z = GetPosition(e)
print("xyz =",x,y,z)

我期望“xyz = 1.0 1.0 1.0” 我得到“xyz = 1.0 nil nil”

执行此操作的正确方法是 lua 看到所有 return 值?

当 Lua 调用您的函数时,它将检查它的 return 值以找出它应该从堆栈中获取多少个值。在你的例子中是 1。 Lua 还怎么知道你想要 return 推送多少个值?

来自Lua 5.4 Reference Manual 4.6 Functions and Types

In order to communicate properly with Lua, a C function must use the following protocol, which defines the way parameters and results are passed: a C function receives its arguments from Lua in its stack in direct order (the first argument is pushed first). So, when the function starts, lua_gettop(L) returns the number of arguments received by the function. The first argument (if any) is at index 1 and its last argument is at index lua_gettop(L). To return values to Lua, a C function just pushes them onto the stack, in direct order (the first result is pushed first), and returns in C the number of results. Any other value in the stack below the results will be properly discarded by Lua. Like a Lua function, a C function called by Lua can also return many results.

As an example, the following function receives a variable number of numeric arguments and returns their average and their sum:

 static int foo (lua_State *L) {
   int n = lua_gettop(L);    /* number of arguments */
   lua_Number sum = 0.0;
   int i;
   for (i = 1; i <= n; i++) {
     if (!lua_isnumber(L, i)) {
       lua_pushliteral(L, "incorrect argument");
       lua_error(L);
     }
     sum += lua_tonumber(L, i);
   }
   lua_pushnumber(L, sum/n);        /* first result */
   lua_pushnumber(L, sum);         /* second result */
   return 2;                   /* number of results */
 }