1. 程式人生 > >csdn學習筆記:lua於c/c++互動

csdn學習筆記:lua於c/c++互動

lua使用一個虛擬棧來和c互傳值。棧上的每一個元素都是一個lua值

所有對棧的api查詢操作都不嚴格遵循棧的操作規則。而是可以用一個索引來指向棧上的任何元素;正的索引指的棧上的絕對位置(從1開始);負的索引則指從棧頂開始的偏移量。

展開來說,如果堆疊有n個元素,那麼索引1表示第一個元素(也就是最先被壓棧的元素)而索引n則是指最後一個元素;索引-1也是指向最後一個元素(即棧頂的元素),索引-n是指第一個元素

                                                                         

push functions (C -> stack)

void lua_pushnil (lua_State * L);

void lua_pushboolean (lua_State * L, int bool); void lua_pushnumber (lua_State * L, lua_Number n);

void lua_pushinteger (lua_State * L, lua_Integer n);

void lua_pushlstring (lua_State * L, const char * s, size_t len); void lua_pushstring (lua_State * L, const char * s);

set function (stack ->lua)

void (lua_setglobal) (lua_State * L, const char * name);

void (lua_settable) (lua_State * L, int idx);

void (lua_setfield) (lua_State * L, int idx, const char * k);

void (lua_seti) (lua_State * L, int idx, lua_Integer n);

void (lua_rawset)

(lua_State * L, int idx);

void (lua_rawseti) (lua_State * L, int idx, lua_Integer n);

void (lua_rawsetp) (lua_State * L, int idx, const void * p);

int (lua_setmetatable) (lua_State * L, int objindex);

void (lua_setuservalue) (lua_State * L, int idx);

​​​​​​​get functions (Lua -> stack)

int (lua_getglobal) (lua_State *L, const char *name);

int (lua_gettable) (lua_State *L, int idx);

int (lua_getfield) (lua_State *L, int idx, const char *k);

int (lua_geti)   (lua_State *L, int idx, lua_Integer n);

int (lua_rawget) (lua_State *L, int idx);

int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);

int (lua_rawgetp) (lua_State *L, int idx, const void *p);

void (lua_createtable) (lua_State *L, int narr, int nrec);

void *(lua_newuserdata) (lua_State *L, size_t sz);

int (lua_getmetatable) (lua_State *L, int objindex);

int (lua_getuservalue) (lua_State *L, int idx);

access functions (stack -> C)不出棧​​​​​​​

int (lua_isnumber) (lua_State *L, int idx);

int (lua_isstring) (lua_State *L, int idx);

int (lua_iscfunction) (lua_State *L, int idx);

int (lua_isinteger) (lua_State *L, int idx);

int (lua_isuserdata) (lua_State *L, int idx);

int (lua_type) (lua_State *L, int idx);

const char *(lua_typename) (lua_State *L, int tp);

lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);

lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);

int (lua_toboolean) (lua_State *L, int idx);

const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);

size_t (lua_rawlen) (lua_State *L, int idx);

lua_CFunction (lua_tocfunction) (lua_State *L, int idx);

API常用介面

LUA_API desc

int lua_gettop(lua_State *L)

  • 返回棧頂元素的索引。
  • 因為棧中元素的索引是從 1 開始編號的, 所以函式的返回值相當於棧中元素的個數。
  • 返回值為 0 表示棧為空。

void lua_settop(lua_State *L, int index)

  • 設定棧頂為索引"index"指向處。
  • 如果"index""lua_gettop()"的值大, 那麼多出的新元素將被賦值為"nil"

lua_settop(L, 0);

// 清空棧。

void lua_pushvalue (lua_State *L, int index);

  • 將索引"index"處元素, 壓到棧頂。(把棧上給定索引處的元素作一個副本壓棧)

void lua_replace(lua_State *L, int index)

  • 將棧頂元素移動到索引"index"處。(棧頂出棧,覆蓋了索引"index"處的元素)

void lua_rotate (lua_State *L, int index, int n);

* idx 開始到棧頂的元素輪轉 n 個位置。 對於 n 為正數時,輪轉方向是向棧頂的; 當 n

* 為負數時,向棧底方向輪轉 -n 個位置。 n 的絕對值不可以比參於輪轉的切片長度大。

常用巨集

#define lua_pop(L,n) lua_settop(L, -(n) - 1)

彈出從棧頂開始的幾個索引

#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))

移除棧中索引"index"處的元素, 該元素之上的所有元素下移。

從給定有效索引處移除一個元素, 把這個索引之上的所有元素移下來填補上這個空隙

#define lua_insert(L,idx) lua_rotate(L, (idx), 1)

將棧頂元素移動到索引"index", 索引"index"()之上的所有元素移。

   
   
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"



static void stackDump(lua_State* L){
	static int count = 0;
	printf("begin dump lua stack %d\n", count);
	int i = 0;
	int top = lua_gettop(L);
	for (i = top; i >=  1; --i){
		int t = lua_type(L, i);
		switch (t)
		{
		case LUA_TSTRING:
			printf("'%s' ", lua_tostring(L, i));
			break;
		case LUA_TBOOLEAN:
			printf(lua_toboolean(L, i) ? "true " : "false ");
			break;
		case LUA_TNUMBER:
			printf("%g ", lua_tonumber(L, i));
			break;
		default:
			printf("%s ", lua_typename(L, t));
			break;
		}
	}
	printf("\nend dump lua stack %d \n", count++);
}



int main(){
	//printf("hello c\n");
	lua_State* L = luaL_newstate();    //建立一個lua虛擬機器(lua上下文),類似於指標
	luaL_openlibs(L);
	lua_pushinteger(L, 21);
	lua_pushinteger(L, 22);
	lua_pushinteger(L, 23);



	stackDump(L);   //列印棧上的內容

	//int lua_gettop(lua_State* L);
	//printf("stack size = %d\n", lua_gettop(L));




	//stack資料為23,22,21
	//lua_settop(L, 5);     //設定索引5為棧頂索引,沒有資料為nil
	//stackDump(L);			//輸出為nil,nil,23,22,21
	//lua_settop(L, -2);    //負數按負數索引走,-2表示從棧頂開始的第二個元素
	//stackDump(L);

	//stack資料為23,22,21
	//lua_pushvalue(L, 2);   //把索引2的資料複製到棧頂,
	//stackDump(L);			//輸出22,23,22,21


	lua_pushinteger(L, 24);
	//stack資料為24,23,22,21
	//lua_replace(L, 2);       //將棧頂元素移動到索引2處,(棧頂出棧,覆蓋了索引2的元素)
	//stackDump(L);			//輸出為23,24,21



	//stack資料為24,23,22,21
	//lua_rotate(L, 2, 1);   
	//把從idx開始到棧頂的元素輪轉n個位置。n為正數,輪轉方向是向棧頂,
	//當n為負數時,向棧底方向輪轉-n個位置,n的絕對值不可以比參與輪轉的切片長度大
	//stackDump(L);			//輸出23,22,24,21

	//lua_rotate(L, 2, -1);  
	//把從idx開始到棧頂的元素輪轉n個位置。n為正數,輪轉方向是向棧頂,
	//當n為負數時,向棧底方向輪轉-n個位置,n的絕對值不可以比參與輪轉的切片長度大
	//stackDump(L);			//輸出22,24,23,21


	//lua_rotate(L, 2, 2);
	//stackDump(L);            //輸出22,24,23,21


	//stack資料為24,23,22,21,如果想把22刪除掉
	/*lua_rotate(L, 2, 2);
	lua_settop(L, -2);
	stackDump(L);*/
	//end


	//##########常用巨集#############
	////#define lua_pop(L,n)   lua_settop(L,-(n)-1)
	//stack資料為24,23,22,21
	//lua_pop(L, 3);   //彈出3個元素
	//stackDump(L);	//輸出21
	//lua_pop(L, -1);  //等價於lua_settop(L,0); 清空棧,儘量不要用負數

	//stack資料為24,23,22,21
	//lua_remove(L, 2);		//remove第二個索引的元素
	//stackDump(L);			//輸出24 23 21
	



	//stack資料為24,23,22,21
	//lua_insert(L, 2);   //把棧頂元素插入到索引位置,其他元素上移,和lua_rotate(L, 2, 1);效果一樣
	stackDump(L);		//輸出23,22,24,21


	lua_close(L);
	system("pause");
	return 0;
}