問題
LibYAML の Lua バインディング モジュールでrequire()
あるLua スクリプトを C プログラムから呼び出したい。lyaml
Lua 5.2 をソースからコンパイルし、モジュールをハッキングして Lua 5.2 で動作するようにしました。githubで見つけることができます。
Lua スクリプトは次のとおりです。Lua 5.1 と 5.2 のどちらでも動作します。
-- foo.lua
require('lyaml')
function hello ()
res = lyaml.load("a: 4\n")
return res.a
end
-- then calling hello() it works like a charm
print( hello() ) -> 4
問題
Programming in Lua, Chapter 25およびLua 5.2 Reference Manualhello()
に従って、スクリプトから呼び出す C プログラムを作成しました。
C プログラムは次のとおりです。
/* foo.c */
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
int main(void)
{
double z;
lua_State *L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, "foo.lua"))
luaL_error(L, "error running script: %s", lua_tostring(L, -1));
lua_getglobal(L, "hello");
if (lua_pcall(L, 0, 1, 0) != 0)
luaL_error(L, "error calling hello: %s", lua_tostring(L, -1));
if (!lua_isnumber(L, -1))
luaL_error(L, "result must be number");
z = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_close(L);
return 0;
}
私は発行をコンパイルします:
gcc -Wall -o foo foo.c -ldl -lm -llua
を実行foo
すると、実行時に次のエラーが表示されます。
PANIC: unprotected error in call tu Lua API (
error running script: error loading module 'lyaml' from file '/path/to/lyaml.so':
/path/to/lyaml.so: undefined symbol: lua_gettop)
Aborted
そこで、呼び出しlyaml
の後に次の行を追加して、C プログラムからロードしようとしました。luaL_openlibs()
luaL_requiref(L, "lyaml", luaopen_package, 1);
再コンパイル後、エラーは次のようになります。
PANIC: unprotected error in call tu Lua API (
error running script:
hello.lua:4: attempt to index global 'lyaml' (a nil value))
Aborted
したがって、lyaml
シンボルがなく、require()
呼び出しが何らかの形で失敗すると思います。
ドキュメントを読んで、フラグをtrueに設定する呼び出しによって設定されるluaL_requiref()
と思いました:modname
glb
void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb);
openf
文字列を引数として関数を呼び出し、その関数が を介して呼び出されたかのようmodname
に、呼び出し結果を に設定します。 glb が true の場合、結果も global に格納されます。 その結果のコピーをスタックに残します。package.loaded[modname]
require
modname
require()
Lua スクリプトで呼び出しをコメントしようとしましたが、結果は同じです。
質問
私は何を間違えましたか?私は何かをするのを忘れていますか?
編集
次のように、非推奨の(削除された)関数/型を代替品で更新するモジュールをハッキングしました。
lua_strlen() -> luaL_len()
luaL_reg -> luaL_Reg
luaL_getn() -> luaL_len()
ただし、Lua スクリプトを使用してlyaml
動作するため、問題は私のハックではないと思います。
オリジナルlyaml
モジュールを Lua 5.1 で試してみました。結果は同じなので、問題は私のハックではないと確信しています。
アップデート
Doug Currie の回答で提案されているように、次の行を追加すると、C プログラムは Lua 5.1 で完全に動作します。ただし、5.2でも同じエラーが発生します。
lyaml = require('lyaml')