c - 如何访问 lua_pcall 调用的 C 函数的返回值?

标签 c lua

我有这个功能:

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);
}

我想让 generic_pcall_wrapper() 返回 sum() 返回的值。

请注意,此函数应该采用许多不同的函数,并且未指定它们如何处理返回值,唯一可靠的值是每个函数返回的数字。

最佳答案

我不太明白的第一件事是需要 lua_pop在求和函数中。对 lua_pop 的调用非常不寻常,并且不存在于 the official examples 中。 .

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;
}

关于原来的问题,在回调sum中,返回值代表有多少结果已压入堆栈。该值由 Lua 运行时使用,Lua API 的用户无法使用。所以如果API用户以后需要这个值,就需要使用Lua函数保存这个值。

使用 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 */
}

然后:

  1. 通用包装器获取堆栈上返回值的数量
  2. 包装器从堆栈中删除这个特殊值
  3. 向调用者返回值的数量
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;
}

关于c - 如何访问 lua_pcall 调用的 C 函数的返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73289619/

相关文章:

不应该循环的代码(带 fork )正在循环

file - Lua 文件处理

lua - 如何创建一个函数来返回传递给它的第一个非零、非空字符串?

parameters - 在Lua中使用arg作为参数名称有副作用吗?

Lua忽略范围变量

c - 如何将 2 的补码转换为机器自然对应的带符号对应项?

c++ - Windows 中用于 C、C++ 的 Eclipse Juno 问题

c - 在 C 中从函数返回 scanf 值

c++ - 使用 lua_newthread 在 C++ 中等效于 Lua coroutine.create

c++ - matlab与c语言dll的连接