前言#
通過上一章所說的lua_is*系列,我們已經(jīng)可以判定數(shù)值的類型,但是這不是我們的最終目的,我們的最終目的是使用這些值,檢測(cè)類型只是來判斷的,而這些存在棧中的值究竟要怎樣用,就要涉及到今天我所列舉的這些api,也就是使用頻率相當(dāng)高的lua_to*系列。
內(nèi)容#
lua_toboolean##
- 原型:int lua_toboolean (lua_State *L, int index)
- 解釋:把指定的索引處的的 Lua 值轉(zhuǎn)換為一個(gè) C 中的 boolean 值( 0 或是 1 )。 和 Lua 中做的所有測(cè)試一樣, lua_toboolean 會(huì)把任何 不同于 false 和 nil 的值當(dāng)作 1 返回; 否則就返回 0 。 如果用一個(gè)無效索引去調(diào)用也會(huì)返回 0 。
lua_tocfunction##
- 原型:lua_CFunction lua_tocfunction (lua_State *L, int index);
- 解釋:把給定索引處的 Lua 值轉(zhuǎn)換為一個(gè) C 函數(shù)。 這個(gè)值必須是一個(gè) C 函數(shù);如果不是就返回 NULL 。
lua_tointeger##
- 原型:lua_Integer lua_tointeger (lua_State *L, int idx);
- 解釋: 把給定索引處的 Lua 值轉(zhuǎn)換為 lua_Integer 這樣一個(gè)有符號(hào)整數(shù)類型。 這個(gè) Lua 值必須是一個(gè)數(shù)字或是一個(gè)可以轉(zhuǎn)換為數(shù)字的字符串, 否則 lua_tointeger 返回 0 。
lua_tolstring##
- 原型:const char *lua_tolstring (lua_State *L, int index, size_t *len);
- 解釋:把給定索引處的 Lua 值轉(zhuǎn)換為一個(gè) C 字符串。 如果 len 不為 NULL , 它還把字符串長(zhǎng)度設(shè)到 *len 中。 這個(gè) Lua 值必須是一個(gè)字符串或是一個(gè)數(shù)字; 否則返回返回 NULL 。 如果值是一個(gè)數(shù)字,lua_tolstring 還會(huì)把堆棧中的那個(gè)值的實(shí)際類型轉(zhuǎn)換為一個(gè)字符串。
lua_tonumber##
- 原型:lua_Number lua_tonumber (lua_State *L, int index);
- 解釋:把給定索引處的 Lua 值轉(zhuǎn)換為 lua_Number 這樣一個(gè) C 類型。 這個(gè) Lua 值必須是一個(gè)數(shù)字或是一個(gè)可轉(zhuǎn)換為數(shù)字的字符串, 否則,lua_tonumber 返回 0 。
lua_topointer##
- 原型:const void *lua_topointer (lua_State *L, int index);
- 解釋: 把給定索引處的值轉(zhuǎn)換為一般的 C 指針 (void*) 。 這個(gè)值可以是一個(gè) userdata ,table ,thread 或是一個(gè) function ; 否則,lua_topointer 返回 NULL 。 不同的對(duì)象有不同的指針。 不存在把指針再轉(zhuǎn)回原有類型的方法。
lua_tostring##
- 原型:const char *lua_tostring (lua_State *L, int index);
- 解釋:等價(jià)于 lua_tolstring ,而參數(shù) len 設(shè)為 NULL 。
lua_tothread##
- 原型:lua_State *lua_tothread (lua_State *L, int index);
- 解釋:把給定索引處的值轉(zhuǎn)換為一個(gè) Lua 線程(由 lua_State* 代表)。 這個(gè)值必須是一個(gè)線程;否則函數(shù)返回 NULL 。
lua_touserdata##
- 原型:void *lua_touserdata (lua_State *L, int index);
- 解釋:如果給定索引處的值是一個(gè)完整的 userdata ,函數(shù)返回內(nèi)存塊的地址。 如果值是一個(gè) light userdata ,那么就返回它表示的指針。 否則返回 NULL 。
Usage##
- 首先我們來新建一個(gè)文件命名為totransformtest.lua,然后在文件中編寫如下代碼:
-- 定義一個(gè)table
information =
{
name = "AlbertS",
age = 20,
sex = "man",
married = false,
}
function func_testtype()
print("lua -- > this is a lua function");
end
- 然后我們來編寫c++的調(diào)用函數(shù),代碼如下:
lua_State *L = lua_open();
luaL_openlibs(L);
luaL_dofile(L,"totransformtest.lua"); // 加載執(zhí)行l(wèi)ua文件
lua_getglobal(L, "func_testtype"); // 函數(shù)入棧
if(lua_isfunction(L, -1)) // -->lua_isfunction用法
{
lua_pcall(L, 0, 0, 0);
}
lua_getglobal(L,"information"); // 將全局表壓入棧
lua_pushstring(L, "name"); // 將要取的變量名壓入棧
lua_rawget(L, -2); // 取information.name的值
if(lua_isstring(L, -1))
{
size_t nNameLen;
printf("c++ --> information.name = %s\n",
lua_tolstring(L, -1, &nNameLen));// -->lua_tolstring用法
printf("c++ --> information.name len = %d\n", nNameLen);
}
lua_pop(L, 1);
lua_pushstring(L, "age"); // 將要取的變量名壓入棧
lua_rawget(L, -2); // 取information.age的值
if(lua_isnumber(L, -1))
{
printf("c++ --> information.age = %d\n",
lua_tointeger(L, -1)); // -->lua_tointeger用法
}
lua_pop(L, 1);
lua_pushstring(L, "sex"); // 將要取的變量名壓入棧
lua_rawget(L, -2); // 取information.sex的值
if(lua_isstring(L, -1))
{
printf("c++ --> information.sex = %s\n",
lua_tostring(L, -1)); // -->lua_tostring用法
}
lua_pop(L, 1);
lua_pushstring(L, "married"); // 將要取的變量名壓入棧
lua_rawget(L, -2); // 取information.married的值
if(lua_isboolean(L, -1))
{
printf("c++ --> information.married = %s\n",
lua_toboolean(L, -1) ? "true" : "false");// -->lua_toboolean
}
lua_pop(L, 1);
lua_close(L); //關(guān)閉lua環(huán)境
- 結(jié)果
總結(jié)#
- 由于lua_toboolean會(huì)把任何不同于 false 和 nil 的值當(dāng)作 1 返回,所以你如果想只接收真正的 boolean 值,就需要使用lua_isboolean來測(cè)試值的類型。
- lua_tolstring 返回 Lua 狀態(tài)機(jī)中字符串的以對(duì)齊指針。這個(gè)字符串總能保證最后一個(gè)字符為零 ('\0') ,而且它允許在字符串內(nèi)包含多個(gè)這樣的零。因?yàn)?Lua 中可能發(fā)生垃圾收集,所以不保證 lua_tolstring 返回的指針,在對(duì)應(yīng)的值從堆棧中移除后依然有效。
- lua_tostring是利用lua_tolstring的一個(gè)宏而已。
- 可能你會(huì)疑惑為什么有l(wèi)ua_isfunction和lua_iscfunction函數(shù),但卻只有l(wèi)ua_tocfunction而沒有l(wèi)ua_tofunction函數(shù),其實(shí)仔細(xì)想想就知道只有轉(zhuǎn)化成c function才有意義,假設(shè)是一個(gè)lua function在c代碼里是沒有用處的。