CでLua関数を呼び出す

6595 ワード

まず簡単な例を見てみましょう
lua_State* L = NULL;

// lua double f(double x, double y) { double z; lua_getglobal(L, "f"); // lua f lua_pushnumber(L, x); // x y lua_pushnumber(L, y); if(lua_pcall(L, 2, 1, 0) != 0) error(L, "error running function 'f': %s", lua_tostring(L, -1)); if(!lua_isnumber(L, -1)) error(L, "function 'f' must return a number"); z = lua_tonumber(L, -1); lua_pop(L, 1); return z; } int main(void) { L = lua_open(); luaL_openlibs(L); if(luaL_loadfile(L, "c:\\luatest\\functest.lua") || lua_pcall(L, 0, 0, 0)) error(L, "cannot run configuration file: %s", lua_tostring(L, -1)); printf("%f
", f(1.0, 2.0)); return 0; }

functest.lua:
f = function(a, b)
    return a + b
end

ここで最も重要なのは呼び出し関数の使用であり、CでLua関数を呼び出すAPIは主に以下のいくつかである.
(1)void lua_call (lua_State *L, int nargs, int nresults);関数呼び出し、nargsはパラメータの個数を表し、nresultsは戻り値の個数を表すlua関数を最初にスタックし、次にパラメータを順次スタックし、最後に関数を呼び出して関数を呼び出すと、パラメータと関数はpopでスタックを出て、呼び出しが戻った後、結果はpushでスタックnresults=LUA_に入るMULTRETでは、すべての戻り値がpushスタックnresultsに入力されます!=LUA_MULTRET、戻り値個数nresultsに基づいてLua文を調整する:
a = f("how", t.x, 14)

Cでの実装:
lua_getglobal(L, "f");        //     
lua_pushstring(L, "how");      //   1  
lua_getglobal(L, "t");       //  t  
lua_getfield(L, -1, "x");       //   2  
lua_remove(L, -2);         //  t  
lua_pushinteger(L, 14);     //   3  
lua_call(L, 3, 1);            //
lua_setglobal(L, "a");         //  a  ,    

上記のコードの実行が完了すると、スタック状態は元に戻ります.
(2)int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);関数呼び出し、セキュリティモードでエラー処理関数を追加できます.呼び出し中にerrorが発生した場合、lua_pcallは取得し、push stackのエラーメッセージ(関数とパラメータpopを先にスタックします)を取得します.また、error code(0以外の値)が返されます.errorが発生した場合、エラー処理関数を指定すると、error messageがスタックに入る前にエラー処理関数が呼び出され、具体的にはmsghパラメータによって決定されます:(1)msgh=0、エラー処理関数を指定せず、スタック情報は変わらない;(2)msgh!=0、msghはエラー処理関数のスタックindexを表し、エラー処理関数はerror messageをパラメータとし、返された新しいerror messageをスタックに入れる.主にerror messageにスタックトラッキングなどのより多くのdebug情報を追加するために使用される.これらの情報はpcall呼び出しが完了した後は収集できないためである.関数返却コード:LUA_OK(0):正常なLUAの呼び出しERRRUN:runtime error   LUA_ERRMEM:メモリ割付エラー、この場合エラー処理関数LUA_は呼び出されませんERRERR:エラー処理関数を呼び出す際にエラーが発生しました.もちろん、エラー処理関数LUAをさらに呼び出すことはありません.ERRGCMM:metamethod.を呼び出すgcタイムズエラーはgcによって引き起こされ、関数自体とは関係ありません.
(3)int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k);関数呼び出し、セキュリティモードで、関数yieldを許可します.