Lua C 函数调用 returns 无

Lua C function call returns nil

我为 Lua 编写了一个简单的 C 插件:

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

static int bar (lua_State *L) {
  double arg1 = luaL_checknumber(L, 1);
  double arg2 = luaL_checknumber(L, 2);
  lua_Number res = arg1 + arg2;
  lua_pushnumber(L, res);
  return 1;
}

int luaopen_foo (lua_State *L) {
  static const struct luaL_Reg foo [] = {
    {"bar", bar},
    {NULL, NULL}
  };
  lua_newtable(L);
  luaL_setfuncs(L, foo, 0);
  lua_setglobal(L, "foo");
  return 1;
}

使用此 GCC 命令成功编译代码:

gcc -W -Wall -g -fPIC -shared -I/usr/include/lua5.3 -o foobar.so foobar.c

在 Lua 5.3 REPL 中,我也能够成功找到并导入模块,但函数调用的返回值始终是 nil:

root@b1898c1cc270:/# lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> local foo = require "foo"
> local res = foo.bar(3.0, 6.0)
> res
nil

没有错误被抛出,因为我能够在返回值之前 printf C 代码中的结果,我知道代码被调用并且结果计算成功。

有什么想法吗?

Edit1:通过不使用局部变量,我得到了这个堆栈跟踪而不是 nil 值:

root@d7340c919be4:/# lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> foo = require "foo"
> res = foo.bar(3.0, 6.0)
stdin:1: attempt to call a nil value (field 'bar')
stack traceback:
    stdin:1: in main chunk
    [C]: in ?

luaL_setfuncs 只是将您的函数注册到 table 中。

改为使用 luaL_newlib。它会创建一个新的 table 并在那里注册您的函数。然后你需要将 table 压入 lua 堆栈。

luaL_newlib (L, foo);
return 1;

至于导致错误的原因,lua_setglobal 从堆栈中弹出库 table,因此 luaopen_foo 不会 return 它。然后(虽然我不明白为什么) require "foo" returns 库的文件路径(字符串)代替,字段 ("foo_filepath").barnil.

因此,删除对 lua_setglobal 的调用可以解决问题,即使您没有按照 Ravi 的建议使用 library-creating 宏 luaL_newlib

要将库 table 设置为全局 foo return 它来自 require,您必须推送一个在执行 lua_setglobal(L, "foo") 之前,将 table 的第二个副本与 lua_pushvalue(L, -1) 一起放入堆栈,留下 table 的原始副本由 luaopen_foo 编辑 return ].