在本節(jié)中,將會(huì)展示Lua如何調(diào)用c函數(shù)sub淑掌,直接看源代碼
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#define LUA_TOP_TYPE(L) {int t = lua_type(L, -1); printf("%s\n", lua_typename(L, t));}
#define LUA_STACK_SIZE(L) printf("stack size: %d \n", lua_gettop(L));
// lua 調(diào)用函數(shù)的時(shí)候蒿讥,會(huì)壓棧,調(diào)用完會(huì)彈棧抛腕,不會(huì)把值殘留到棧中
int sub(lua_State* L) {
// lua 函數(shù)調(diào)用的時(shí)候芋绸,新Block對(duì)應(yīng)新的虛擬棧,不受上一層干擾
int topNum = lua_gettop(L);
printf("sub topNum: %d \n", topNum);
int x = lua_tonumber(L, 1);
int y = lua_tonumber(L, 2);
lua_pushnumber(L, x - y);
return 1;
}
int main()
{
lua_pushcfunction(L, sub);
LUA_TOP_TYPE(L);
// sub in virtual to lua
lua_setglobal(L, "mysub");// 等價(jià)于在lua植入代碼 mysub = sub
LUA_TOP_TYPE(L);
lua_pushnumber(L, 11);
lua_pushnumber(L, 12);
lua_pushnumber(L, 13);
lua_pushnumber(L, 13);
LUA_STACK_SIZE(L); // 此時(shí)打印4
//執(zhí)行mysub,并傳入3個(gè)參數(shù)
luaL_dostring(L, "print(mysub(2, 1, 10))");
lua_close(L);
return 1;
}
// 運(yùn)行結(jié)果: 打印1
注意c函數(shù)以及調(diào)用此行的代碼担敌,這幾行代碼解析如下:
luaL_dostring(L, "print(mysub(2, 1, 10))"); // 參數(shù)壓棧摔敛,該棧為10, 1, 2,執(zhí)行完之后棧會(huì)被清空柄错,不影響外部棧
int sub(lua_State* L) {
int topNum = lua_gettop(L); // 3個(gè)元素舷夺,棧的順序?yàn)?0, 1售貌, 2
printf("sub topNum: %d \n", topNum);
int x = lua_tonumber(L, 1); // 獲取棧底第一個(gè)元素 2
int y = lua_tonumber(L, 2); // 獲取棧底第二個(gè)元素
lua_pushnumber(L, x - y); // 將結(jié)果壓入棧
return 1; //提示返回結(jié)果只有一個(gè)值
}
然后函數(shù)返回值由1改為2给猾,那么打印的結(jié)果為{10, 1}, 因?yàn)楹瘮?shù)調(diào)用完,棧上的值為x-y, 10, 1, 2颂跨,而返回值要求返回兩個(gè)敢伸。依此談棧進(jìn)入print參數(shù)10, x-y
而如果代碼是
X = mysub(2,1,10)
那么X的值只為1,因?yàn)閄只取棧頂?shù)闹?/p>