C中呼叫Lua函式
我們先來看一個簡單的例子:
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。
相關文章
- 透過例子學習Lua(7)--呼叫C/C++函式(轉)C++函式
- xLua中C#呼叫LuaC#
- xLua中Lua呼叫C#C#
- Lua中呼叫ref和out修飾引數的函式/過載函式函式
- C++中函式呼叫的用法C++函式
- toLua中Lua呼叫C#中的類C#
- lua呼叫c程式C程式
- C++呼叫LuaC++
- 透過例子學習Lua(6)--C/C++中用Lua函式(轉)C++函式
- Lua封裝函式模組並由其他模組呼叫封裝函式
- C程式函式呼叫&系統呼叫C程式函式
- 透過例子學習Lua(4)--函式的呼叫(轉)函式
- C++呼叫Lua API介面C++API
- C語言函式呼叫棧C語言函式
- JS中函式內套函式的呼叫JS函式
- Visual C++中函式呼叫方式淺探 (轉)C++函式
- C++如何解析函式呼叫C++函式
- [C++]顯示呼叫建構函式和解構函式C++函式
- C++箴言:避免解構函式呼叫虛擬函式C++箴言函式
- 避免SQL中的函式呼叫SQL函式
- Matlab中@與函式呼叫Matlab函式
- Lua 和 C/C++ 互相呼叫例項分析C++
- lua非全域性函式函式
- c# tcbs之建構函式呼叫建構函式示例C#函式
- C++入門教程(11):呼叫函式C++函式
- 【C#學習筆記】函式呼叫C#筆記函式
- js 使用 DotNetObjectReference 呼叫 c# 函式JSObjectC#函式
- 如何使用函式指標呼叫類中的函式和普通函式函式指標
- [轉]Cocos2d-x下Lua呼叫自定義C++類和函式的最佳實踐C++函式
- [譯] 解析 Go 中的函式呼叫Go函式
- 在PowerBuilder中動態呼叫函式UI函式
- vue在一個函式中呼叫另外一個函式Vue函式
- C++程式中不同函式呼叫方式的彙編碼比較C++函式
- Swift3.0 呼叫C函式-_silen_nameSwift函式
- STM32呼叫C庫自帶函式函式
- C語言中庫函式呼叫幾例(轉)C語言函式
- C++函式呼叫棧從何而來C++函式
- C/C++—— C++中函式重寫和函式過載C++函式