csdn學習筆記:lua呼叫c/c++
阿新 • • 發佈:2018-11-09
無論何時lua呼叫c,被呼叫的函式都得到一個新的棧,這個棧獨立於c函式本身的棧,也獨立於之前的lua棧。它裡面包含了lua傳遞給c函式的所有引數,而c函式則把要返回的結果放入這個棧以返回個呼叫者
setglobal
void lua_setglobal (lua_State *L, const char *name);
將虛擬棧中,將棧頂元素彈出,作為全域性 lua 變數 name 的值。
lua_newtable
void lua_newtable (lua_State *L);
產生一個空表, 並推入棧。
settable
void lua_settable (lua_State *L, int index);
作一個等價於 t[k] = v 的操作,這裡 t 是一個給定有效索引 index 處的值,v 指棧頂的值, 而 k 是棧頂之下的那個值。lua_settable會把棧頂作為value,棧頂的下一個作為key設定到index指向的table,最後把這兩個全部彈出棧,這時候settable完成。
lua_setfield
void lua_setfield (lua_State *L, int index, const char *k);
上式,等價於 t[k] = v,t 是棧上索引為index 的表,v 是棧頂的值。函式結束,棧頂值 v會被彈出。
lua訪問c中的棧變數
int age = 18; char* org = "nzhsoft"; lua_pushinteger(L, age); lua_setglobal(L, "nianling"); //lua裡面的變數是nianling,把age推到lua 的全域性變數棧中 lua_pushstring(L, org); lua_setglobal(L, "org"); lua檔案 ----lua訪問c中的變數 print("age=",nianling); print("org=",org); --------------------------------------- output: age=18 org=nzhsoft
Lua訪問c的table表
lua_newtable(L); //建立一個表併入棧 idx = -1
lua_pushstring(L, "age");
lua_pushinteger(L, 18); //stack , -1:18, -2:age, -3:table表
printf("stack size = %d\n", lua_gettop(L));
lua_settable(L, -3); //table 在-3的索引,執行settable後,table表在-1位置
printf("stack size = %d\n", lua_gettop(L));
lua_pushstring(L, "org");
lua_pushstring(L, "fangfang"); //stack , -1:fangfang, -2:org, -3:table表
lua_settable(L, -3); //table 在-3的索引,執行settable後,table表在-1位置
lua_setglobal(L, "tab"); //這裡就會清空棧, stack size = 0;
lua檔案
print("age=",tab.age);
print("org=",tab.org);
-----------------------------------
output:
stack size = 3
stack size = 1
age= 18
org= fangfang
上面程式碼用lua_setfield實現
lua_newtable(L); //建立一個表併入棧 idx = -1
lua_pushinteger(L, 18);
lua_setfield(L, -2, "age");
lua_pushstring(L, "fangfang");
lua_setfield(L, -2, "org");
lua_setglobal(L, "tab"); //這裡就會清空棧, stack size = 0;
------------------------------------------------------------------
output:
stack size = 2
stack size = 1
age= 18
org= fangfang
lua訪問c的函式
c函式
//無參無返回
int func(lua_State* L){
printf("hello lua\n");
return 0;
}
//有參無返回
int func2(lua_State* L){
//func2(888,"fangfang") lua是這樣呼叫的,第一個引數先入棧,第二個引數後入棧 -1:"fangfang", -2:888
int num = lua_tointeger(L, -2);
char* str = lua_tostring(L, -1);
printf("num = %d\n", num);
printf("str = %s\n", str);
return 0;
}
//有參有返回
int func3(lua_State* L){
int count = lua_gettop(L);
int sum = 0;
for (int i = 1; i <= count; i++){
sum += lua_tointeger(L, i);
}
printf("stack size = %d\n", lua_gettop(L));
lua_pushinteger(L, sum);
printf("stack size = %d\n", lua_gettop(L));
return 1; //1返回1個引數,2返回2個引數
}
main函式
lua_pushcfunction(L, func);
lua_setglobal(L, "func");
lua_pushcfunction(L, func2);
lua_setglobal(L, "func2");
lua_pushcfunction(L, func3);
lua_setglobal(L, "func3);
lua檔案
func() --無參無返回
func2(888,"fangfang") --有參無返回
num = func3(100,200); --有參有返回
print(num);
----------------------------------------------------
output:
hello lua
num = 888
str = fangfang
stack size = 2
stack size = 3
300
返回多個c函式為一個表(c函式表)
int printHello(lua_State* L){
lua_pushstring(L, "hello lua");
return 1;
}
int foo(lua_State* L){
int n = lua_gettop(L);
if (n != 0){
int i = lua_tonumber(L, 1);
lua_pushnumber(L, i + 1);
return 1;
}
return 0;
}
int add(lua_State* L){
int n = lua_gettop(L);
int sum = 0;
for (int i = 1; i <= n; i++){
sum += lua_tonumber(L, i);
}
if (n != 0){
lua_pushnumber(L, sum);
return 1;
}
return 0;
}
static const luaL_Reg myLib[] = {
{ "printHello", printHello },
{ "foo", foo },
{ "add", add },
{ NULL, NULL }
};
main函式
const luaL_Reg* libf = myLib;
for (; libf->func; libf++){ //這裡的條件就是libf->func不為NULL
lua_register(L, libf->name, libf->func);
lua_settop(L, 0);
}
lua檔案
sum = add(100,200,300);
print(sum);
print(printHello());
print(foo(100));
----------------------------------------------
output:
600.0
hello lua
101.0
c提供函式為table供lua使用 (luaL_requiref)
int printHello(lua_State* L){
lua_pushstring(L, "hello lua");
return 1;
}
int foo(lua_State* L){
int n = lua_gettop(L);
if (n != 0){
int i = lua_tonumber(L, 1);
lua_pushnumber(L, i + 1);
return 1;
}
return 0;
}
int add(lua_State* L){
int n = lua_gettop(L);
int sum = 0;
for (int i = 1; i <= n; i++){
sum += lua_tonumber(L, i);
}
if (n != 0){
lua_pushnumber(L, sum);
return 1;
}
return 0;
}
static const luaL_Reg myLib[] = {
{ "printHello", printHello },
{ "foo", foo },
{ "add", add },
{ NULL, NULL }
};
int luaOpen_my(lua_State* L){
luaL_newlib(L, myLib);
return 1;
}
main函式
luaL_requiref(L, "my", luaOpen_my, 1); //“my”到時候lua呼叫的時候使用的table的字首
lua檔案
sum = my.add(100,200,300);
print(sum);
print(my.printHello());
print(my.foo(100));
------------------------------------------------
output:
600.0
hello lua
101.0