简体   繁体   English

如何访问 lua_pcall 调用的 C function 的返回值?

[英]How to access the return value of a C function called by lua_pcall?

I have this function:我有这个 function:

static int generic_pcall_wrapper(lua_State* L, int (*funct)(lua_State*)){
    int narg = lua_gettop(L);
    lua_pushcfunction(L, funct);
    lua_rotate(L, 1, 1);

    int res = lua_pcall(L, narg, LUA_MULTRET, 0);
    if(res != 0){
        //handle error
    }
    return ??; // I would like to return 1 as in sum()
}

static int sum(lua_State* L){
    int a = lua_tointeger(L, -1);
    int b = lua_tointeger(L, -2);    
    lua_pop(L, 1);   
    lua_pushnumber(L, a + b);
    return 1;
}

static int foo(lua_State* L){
    return generic_pcall_wrapper(L, sum);
}

I would like to have generic_pcall_wrapper() to return the value returned by sum().我想让 generic_pcall_wrapper() 返回 sum() 返回的值。

Note that this function should take many different functions, and how they deal with the return values is unspecified, the only reliable value is the number returned by each of those functions.请注意,此 function 应该采用许多不同的函数,并且未指定它们如何处理返回值,唯一可靠的值是每个函数返回的数字。

The first thing which I don't quite understand is the need for lua_pop in the sum function.我不太明白的第一件事是总和function中需要lua_pop This call to lua_pop is quite unusual and not present in the official examples .这个对 lua_pop 的调用非常不寻常,并且在官方示例中没有出现。

static int sum(lua_State* L)
{
  int a = lua_tointeger(L, -1);
  int b = lua_tointeger(L, -2);    
  lua_pop(L, 1); /* unusual, probably not needed */
  lua_pushnumber(L, a + b);
  return 1;
}

Regarding the original question, in the callback sum , the return value represent how many results have been pushed on the stack.关于原始问题,在回调sum中,返回值表示已将多少结果压入堆栈。 This value is consumed by the Lua runtime and is not available to the user of the Lua API.此值由 Lua 运行时使用,并且对 Lua API 的用户不可用。 So if this value is needed later by the API user, it is needed to save this value using the Lua functions.因此,如果 API 用户稍后需要此值,则需要使用 Lua 函数保存此值。

With the Lua API, a natural way to do that would be to push it on the stack.对于 Lua API,很自然的做法是将其推入堆栈。

static int sum(lua_State* L)
{
  int a = lua_tointeger(L, -1);
  int b = lua_tointeger(L, -2);
  lua_pushnumber(L, a + b); /* push the result of sum          */
  lua_pushinteger(L, 1);    /* sum return 1 value on the stack */
  return 2; /* return all the values (sum) and then #values */
}

Then:然后:

  1. The generic wrapper get the number of returned values on the stack通用包装器获取堆栈上返回值的数量
  2. The wrapper remove this special value from the stack包装器从堆栈中移除这个特殊值
  3. Return to the number of values to the caller返回给调用者的值的数量
static int generic_pcall_wrapper(lua_State* L, int (*funct)(lua_State*))
{
  int narg = lua_gettop(L);
  lua_pushcfunction(L, funct);

  //push argument again, but above the function
  int stack_size = lua_gettop(L);
  
  for (int i = 1; i < stack_size; i++)
    lua_pushvalue(L, i);
    
  int res = lua_pcall(L, narg, LUA_MULTRET, 0);

  /* Get the number of values which have been pushed */
  int res_count = lua_tointeger(L, -1);

  /* Remove the number of values */
  lua_pop(L);

  return res_count;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM