Я написал простой плагин C для 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;
}
Код успешно скомпилирован с помощью этой команды GCC:
gcc -W -Wall -g -fPIC -shared -I/usr/include/lua5.3 -o foobar.so foobar.c
В REPL Lua 5.3 я также могу успешно найти и импортировать модуль, но возвращаемое значение вызова функции всегда равно 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: не используя локальные переменные, я получаю эту трассировку стека вместо нулевого значения:
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 ?
local
в сеансе интерактивного интерпретатора. - person siffiejoe   schedule 06.04.2018lua_setglobal
извлекает вашу таблицу модулей из стека Lua, поэтому вы не можетеreturn 1
из вашейluaopen_foo
функции, если вы сначала не продублируете слот стека с помощьюlua_pushvalue
. - person siffiejoe   schedule 06.04.2018lua_setglobal
, потому что считаю, что это правильный способ регистрации модуля в 5.3, посколькуregister
иlua_register
устарели в 5.2. Как модуль должен быть зарегистрирован нормально? - person m_vdbeek   schedule 06.04.2018lua_open
иlua_register
* - person m_vdbeek   schedule 06.04.2018require
(и, следовательно, функцииluaopen_*
). Таким образом,lua_newtable
+luaL_setfuncs
подходит, как и использованиеluaL_newlib
(что примерно эквивалентно приведенной выше комбинации). Но если вы хотите установить глобальный и вернуть таблицу модулей из функцииluaopen_*
, вы должны сначала продублировать ее в стеке. - person siffiejoe   schedule 06.04.2018