前言#
通過上一章所說的lua_is*系列处嫌,我們已經(jīng)可以判定數(shù)值的類型荠藤,但是這不是我們的最終目的斩个,我們的最終目的是使用這些值,檢測類型只是來判斷的乓搬,而這些存在棧中的值究竟要怎樣用思犁,就要涉及到今天我所列舉的這些api,也就是使用頻率相當(dāng)高的lua_to*系列进肯。
內(nèi)容#
lua_toboolean##
- 原型:int lua_toboolean (lua_State *L, int index)
- 解釋:把指定的索引處的的 Lua 值轉(zhuǎn)換為一個 C 中的 boolean 值( 0 或是 1 )激蹲。 和 Lua 中做的所有測試一樣, lua_toboolean 會把任何 不同于 false 和 nil 的值當(dāng)作 1 返回江掩; 否則就返回 0 学辱。 如果用一個無效索引去調(diào)用也會返回 0 。
lua_tocfunction##
- 原型:lua_CFunction lua_tocfunction (lua_State *L, int index);
- 解釋:把給定索引處的 Lua 值轉(zhuǎn)換為一個 C 函數(shù)环形。 這個值必須是一個 C 函數(shù)策泣;如果不是就返回 NULL 。
lua_tointeger##
- 原型:lua_Integer lua_tointeger (lua_State *L, int idx);
- 解釋: 把給定索引處的 Lua 值轉(zhuǎn)換為 lua_Integer 這樣一個有符號整數(shù)類型抬吟。 這個 Lua 值必須是一個數(shù)字或是一個可以轉(zhuǎn)換為數(shù)字的字符串萨咕, 否則 lua_tointeger 返回 0 。
lua_tolstring##
- 原型:const char *lua_tolstring (lua_State *L, int index, size_t *len);
- 解釋:把給定索引處的 Lua 值轉(zhuǎn)換為一個 C 字符串火本。 如果 len 不為 NULL 危队, 它還把字符串長度設(shè)到 *len 中。 這個 Lua 值必須是一個字符串或是一個數(shù)字钙畔; 否則返回返回 NULL 茫陆。 如果值是一個數(shù)字,lua_tolstring 還會把堆棧中的那個值的實際類型轉(zhuǎn)換為一個字符串擎析。
lua_tonumber##
- 原型:lua_Number lua_tonumber (lua_State *L, int index);
- 解釋:把給定索引處的 Lua 值轉(zhuǎn)換為 lua_Number 這樣一個 C 類型簿盅。 這個 Lua 值必須是一個數(shù)字或是一個可轉(zhuǎn)換為數(shù)字的字符串, 否則揍魂,lua_tonumber 返回 0 桨醋。
lua_topointer##
- 原型:const void *lua_topointer (lua_State *L, int index);
- 解釋: 把給定索引處的值轉(zhuǎn)換為一般的 C 指針 (void*) 。 這個值可以是一個 userdata 现斋,table 喜最,thread 或是一個 function ; 否則步责,lua_topointer 返回 NULL 返顺。 不同的對象有不同的指針。 不存在把指針再轉(zhuǎn)回原有類型的方法蔓肯。
lua_tostring##
- 原型:const char *lua_tostring (lua_State *L, int index);
- 解釋:等價于 lua_tolstring 遂鹊,而參數(shù) len 設(shè)為 NULL 。
lua_tothread##
- 原型:lua_State *lua_tothread (lua_State *L, int index);
- 解釋:把給定索引處的值轉(zhuǎn)換為一個 Lua 線程(由 lua_State* 代表)蔗包。 這個值必須是一個線程秉扑;否則函數(shù)返回 NULL 。
lua_touserdata##
- 原型:void *lua_touserdata (lua_State *L, int index);
- 解釋:如果給定索引處的值是一個完整的 userdata 调限,函數(shù)返回內(nèi)存塊的地址舟陆。 如果值是一個 light userdata ,那么就返回它表示的指針耻矮。 否則返回 NULL 秦躯。
Usage##
- 首先我們來新建一個文件命名為totransformtest.lua,然后在文件中編寫如下代碼:
-- 定義一個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會把任何不同于 false 和 nil 的值當(dāng)作 1 返回踱承,所以你如果想只接收真正的 boolean 值,就需要使用lua_isboolean來測試值的類型哨免。
- lua_tolstring 返回 Lua 狀態(tài)機中字符串的以對齊指針茎活。這個字符串總能保證最后一個字符為零 ('\0') ,而且它允許在字符串內(nèi)包含多個這樣的零琢唾。因為 Lua 中可能發(fā)生垃圾收集载荔,所以不保證 lua_tolstring 返回的指針,在對應(yīng)的值從堆棧中移除后依然有效采桃。
- lua_tostring是利用lua_tolstring的一個宏而已懒熙。
- 可能你會疑惑為什么有l(wèi)ua_isfunction和lua_iscfunction函數(shù),但卻只有l(wèi)ua_tocfunction而沒有l(wèi)ua_tofunction函數(shù)芍碧,其實仔細想想就知道只有轉(zhuǎn)化成c function才有意義煌珊,假設(shè)是一個lua function在c代碼里是沒有用處的。