I wrote a simple C plugin for Lua:
#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;
}
The code is compiled successfully with this GCC command:
gcc -W -Wall -g -fPIC -shared -I/usr/include/lua5.3 -o foobar.so foobar.c
In a Lua 5.3 REPL, I'm able to find and import the module successfully as well, but the returned value of the function call is always 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
No errors are thrown and since I'm able to printf
the result in the C code before returning the value, I know the code is called and the result calculated successfully.
Any ideas?
Edit1: By not using local variables I get this stack trace instead of a nil value:
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 just registers your functions into a table.
Instead, use luaL_newlib
. It creates a new table and registers your functions there. Then you need to push the table on to lua stack.
luaL_newlib (L, foo);
return 1;
As to what's causing the error, lua_setglobal
pops the library table from the stack, so that luaopen_foo
does not return it. Then (though I don't understand why) require "foo"
returns the file path of the library (a string) instead, and the field ("foo_filepath").bar
is nil
.
So, removing the call to lua_setglobal
fixes the problem, even if you do not use the library-creating macro luaL_newlib
as Ravi recommends.
To set the library table as global foo
and return it from require
, you have to push a second copy of the table to the stack with lua_pushvalue(L, -1)
before doing lua_setglobal(L, "foo")
, leaving the original copy of the table to be returned by luaopen_foo
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.