1. 程式人生 > 其它 >Lua向C函式中傳遞table引數

Lua向C函式中傳遞table引數

技術標籤:Lualuac++指令碼語言

C向Lua函式傳遞table引數請參考:C向Lua函式傳遞table引數

  • 傳遞純陣列引數

test.lua

mytest = nil
mytest = require "iTest"
if not mytest then
    print("Failed to require iTest!")
else
	print("Succend to require iTest!");
end

function TestFunc()
    local testtabl = {4,8,9,7,1,0,3,2,6,5} --需要傳遞的table
	print("Func_maxvalue:",mytest.getmaxvalue(10,testtabl)) --呼叫C函式
end

test.c

int LuaGetMaxValue(lua_State* L)
{
	int maxvalue = 0;
	int count = lua_tonumber(L,1);

	for (int i = 0; i < count; ++i)
	{
		lua_pushnumber(L, i+1);
		lua_gettable(L, -2);
		int tempnum = lua_tointeger(L, -1);
		if (tempnum > maxvalue)
		{
			maxvalue = tempnum;
		}
		printf("table[%d]=%d\n",i,tempnum);
		lua_pop(L, 1);
	}
	lua_pop(L, 2);
	printf("stack size = %d\n", lua_gettop(L)); 

	lua_pushnumber(L,maxvalue);
	return 1;
}
static const luaL_Reg TestLua[] =
{
	{"getmaxvalue",LuaGetMaxValue},
	{ NULL, NULL }
};

int Luaopen_TestLua(lua_State* L)
{
	if (L == NULL)
	{
		return 1;
	}
	luaL_checkversion(L);
	luaL_newlib(L,TestLua);
	return 1;
}


/*******************************************************************************/

lua_State *L = luaL_newstate();					//返回一個指向棧頂的指標
if(L == nullptr)
{
	return;
}
//獲取相應lua庫的使用權
luaopen_base(L);
luaopen_table(L);
luaopen_package(L);
luaopen_io(L);
luaopen_string(L);

luaL_requiref(L, "iTest", Luaopen_TestLua, 1);
luaL_openlibs(L);

if(luaL_dofile(L,"Test.lua"))  //luaL_dofile巨集封裝了luaL_Loadfile和lua_pcall
{  
	const char * error = lua_tostring(L, -1);
	printf(error);
	return;
}  

lua_getglobal(L,"TestFunc");
lua_pcall(L,0,0,0);

lua_close(L); 
/*******************************************************************************/

輸出

  • 傳遞複雜陣列

test.lua

mytest = nil
mytest = require "iTest"
if not mytest then
    print("Failed to require iTest!")
else
	print("Succend to require iTest!");
end

local tTest = --需要傳遞的table
{
	gdp = 1234,
	info = "this is test about exchange table data!",
	task = {12, 23, 34, 45},
}

function TestFunc()
	mytest.testtable(tTest) --呼叫C函式
end

test.c

int LuaTestTable(lua_State* L)
{
	printf("stack size = %d\n", lua_gettop(L)); //列印棧中元素的個數

	lua_pushstring(L, "gdp");            //將gdp字串壓入棧頂
	//根據棧頂的key獲取table中的value,將key(這裡的“gdp”)移除,再將value壓入棧頂
	lua_gettable(L, 1);                      
	printf("%s\n", lua_tostring(L, -1)); //取棧頂元素(注意這裡的整型值都是string型別)
	lua_pop(L, 1); //取完之後清理棧頂
	printf("stack size = %d\n", lua_gettop(L)); //列印棧中元素的個數

	lua_pushstring(L, "info");   //同上
	lua_gettable(L, 1);
	printf("%s\n", lua_tostring(L, -1));
	lua_pop(L, 1);
	printf("stack size = %d\n", lua_gettop(L));

	lua_pushstring(L, "task"); //這裡的value值是一個table哦,沒關係棧操作都是一樣的
	lua_gettable(L, 1);
	for (int i = 0; i < 4; ++i)
	{
		lua_pushnumber(L, i+1);
		lua_gettable(L, -2);
		printf("%s\n", lua_tostring(L, -1));
		lua_pop(L, 1);
	}
	lua_pop(L, 1);
	printf("stack size = %d\n", lua_gettop(L)); //到這裡tTest表依然在棧底,但不影響後面的操作。
	
	//------華麗的分割線------------//
	//到這裡table資料的解析就結束了,以下內容是c API給lua返回table資料

	lua_newtable(L);//要給lua指令碼返回一個table型別,先要new一個,壓入棧頂
	lua_pushnumber(L, 1); //將key先壓入棧
	lua_pushstring(L, "table2lua"); //再將value壓入棧
	lua_settable(L, -3);//settable將操作-2,-1編號的鍵值對,設定到table中,並把key-value從棧中移除

	lua_pushstring(L, "key"); //同上
	lua_newtable(L); //這裡有個子table
	lua_pushstring(L, "capi");
	//這裡的value型別使用lua_CFunction型別,可用做c API呼叫,函式實現請參看附錄1
	lua_pushcfunction(L, LuaSayHello); 
	lua_settable(L, -3);
	lua_pushnumber(L, 2);
	lua_pushnumber(L, 10086);
	lua_settable(L, -3);
	lua_settable(L, -3); //這個從這裡“lua_pushstring(L, "key"); //同上”開始匹配的
	printf("stack size = %d\n", lua_gettop(L));
	return 1; //返回棧頂1個元素
}

static const luaL_Reg TestLua[] =
{
	{"testtable",LuaTestTable},
	{ NULL, NULL }
};

int Luaopen_TestLua(lua_State* L)
{
	if (L == NULL)
	{
		return 1;
	}
	luaL_checkversion(L);
	luaL_newlib(L,TestLua);
	return 1;
}


/*******************************************************************************/

lua_State *L = luaL_newstate();					//返回一個指向棧頂的指標
if(L == nullptr)
{
	return;
}
//獲取相應lua庫的使用權
luaopen_base(L);
luaopen_table(L);
luaopen_package(L);
luaopen_io(L);
luaopen_string(L);

luaL_requiref(L, "iTest", Luaopen_TestLua, 1);
luaL_openlibs(L);

if(luaL_dofile(L,"Test.lua"))  //luaL_dofile巨集封裝了luaL_Loadfile和lua_pcall
{  
	const char * error = lua_tostring(L, -1);
	printf(error);
	return;
}  

lua_getglobal(L,"TestFunc");
lua_pcall(L,0,0,0);

lua_close(L); 
/*******************************************************************************/

輸出