2012-07-14 10 views
5

問題

私はCプログラムから、require() S lyamlモジュール、LuaがLibYAMLのバインディングのLuaスクリプトを呼び出したいです。Luaの5.2 CのAPIと必要

ソースから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以下、スクリプトからhello()を呼び出す必要がありますCプログラムを書きましたLua 5.2 Reference Manual

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

私が発行するコンパイル:だから私が試した

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 

:次に

gcc -Wall -o foo foo.c -ldl -lm -llua 

fooを実行している、私は、実行時に次のエラーが発生しますCプログラムからlyamlをロードし、0の後に次の行を追加しますコール:

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()呼び出しが何らかの形で失敗します。

luaL_requiref()ドキュメントを読むことで、私はmodnameがtrueにglbフラグを設定するの呼び出しによって設定されるだろうと思った:

void luaL_requiref (lua_State *L, const char *modname, 
        lua_CFunction openf, int glb); 

Calls function openf with string modname as an argument and sets the call result in package.loaded[modname] , as if that function has been called through require .

If glb is true, also stores the result into global modname .
Leaves a copy of that result on the stack.

私はLuaのスクリプト内require()コールをコメントしようとしましたが、結果は同じです。

質問

どうしたのですか?私は何かを忘れていますか?


EDIT

私は次のようにその代替と非推奨(削除)機能/タイプを更新モジュールをハッキング:

lua_strlen() -> luaL_len() 
luaL_reg  -> luaL_Reg 
luaL_getn() -> luaL_len() 

しかしlyaml作業を使用してのLuaスクリプトは、私は問題はないと思います私のハック。

ルア5.1のオリジナルlyamlモジュールを試しました。結果は同じなので、問題は私のハックではないと確信しています。彼の答えにダグ・クリーによって示唆されているように、次の行を追加し

UPDATE

は、Cプログラムは、Luaの5.1と完璧に動作します。私はまだ5.2で同じエラーが発生します。書かれたよう

lyaml = require('lyaml') 
+0

"モジュールをハッキングして、Lua 5.2で動作させるようにしました。"あなたはそれを正しくハッキングしましたか?元のモジュールを使用していない場合は、実際のコードを見ずに正しく動作するかどうかを知る方法がありません。また、Luabindはこれと何をしなければならないのですか? 'lyaml'はそれを使用していますか? –

+0

@NicolBolas [luabind]に申し訳ありません。私はそれを使うことは言及していませんでした。私はハックについてさらに説明を加えました。 – dave

+0

@NicolBolas私がアップデートで報告したように、私はLua 5.1とオリジナルの 'lyaml'モジュールと同じシナリオを実行しました。結果は同じです。私は、議決を締め切る前に、問題に関する詳細な情報を求めることが、尊敬の念と練習になると言います。ありがとうございました。 – dave

答えて

5

foo.luaはLuaの5.1.xの中で実行されます - あなたのハッキングlyaml.cは、グローバルlyamlを設定しませんし、どちらのLua 5.2で必要ありません。最初のテストを実行したときにあなたのPATHがLua 5.2を持っていなかったと思われます。そうでない場合はfoo.luaをロードする前に手動でlyamlを設定してください。

foo.lua

lyaml = require('lyaml') 
+0

'foo.lua'はLua 5.1と5.2のどちらでも動作します。私は '(' lyaml ')をrequireして、両方のバージョンでモジュールと対話的に作業することさえできます。この問題は、Cプログラムから 'hello()'を呼び出そうとしたときに表示されます。どのようにグローバルな 'lyaml'を設定するのですか?私は 'luaL_requiref()'を書いたように、成功しなかった。ありがとう。 – dave

+0

'lyaml.so'の' luaopen_lyaml'がモジュールテーブルを返す限り、5.1と5.2の互換性のあるアプローチで私の補遺を見てください。これはgit repoで正しく動作するようです。 –

+0

'lyaml = require( 'yaml')'を追加すると、Cプログラムは5.1で動作します! 5.2では、同じエラーを返します...理由を理解できません。 Luaはデフォルトで '-DLUA_COMPAT_ALL'でコンパイルされます。 – dave

5

で始まる必要があり、私は解決...すべての問題の根はluaL_requiref()の悪い使用しました。私は、この触発されてしまったthis thread読む

フォローアップ:

In Lua 5.2, libraries no longer create globals; they just return the library table.

luaL_openlibs calls luaL_requiref instead of calling luaopen_* , and luaL_requiref sets the corresponding globals.

をので、モジュールをロードするためにluaL_requiref()を呼び出し、lyamlグローバルに設定する必要があります。

私は

luaL_requiref(L, "lyaml", luaopen_package, 1); 

を使用してみましたが、luaopen_package()はLuaの標準packageモジュール用ローダ機能であるので、それは完全に間違っているのです...私が代わりに使用していた質問で述べたように:

luaL_requiref(L, "lyaml", luaopen_lyaml, 1); 

コンパイルすると

gcc -L/path/to/5.2 -Wall -o foo foo.c -ldl -lm -llua -l:lyaml.so.1 

〜へluaopen_lyaml()にしてください。 Luaの5.1では


、ダグ・カリーは、CプログラムでluaL_requiref()を呼び出さずに、hello.lua

lyaml = require('lyaml') 

を発行するのに十分だった、言ったように。

関連する問題