1. 程式人生 > >csdn學習筆記:lua呼叫c/c++

csdn學習筆記:lua呼叫c/c++

無論何時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