tolua++ 綁定層常用 tolua_tonumber、tolua_tostring 等 API 從 Lua 堆疊取參數,原型:
lua_Number tolua_tonumber(lua_State* L, int narg, lua_Number def);
const char* tolua_tostring(lua_State* L, int narg, const char* def);
程式設計師預期:參數缺失、型別錯誤、傳 nil 皆回傳 def。
實際實作(偷懶版):
TOLUA_API lua_Number tolua_tonumber(lua_State* L, int narg, lua_Number def) {
return lua_gettop(L) < abs(narg) ? def : lua_tonumber(L, narg);
}
TOLUA_API const char* tolua_tostring(lua_State* L, int narg, const char* def) {
return lua_gettop(L) < abs(narg) ? def : lua_tostring(L, narg);
}
只有「參數完全未傳(堆疊不足)」才回傳 def;傳 nil 或型別不符時,直接呼叫 Lua C API,行為為:
lua_tonumber:非數值 → 回傳 0lua_tostring:非字串 → 回傳 NULL// 案例 1:空指標崩潰
const char* name = tolua_tostring(L, 1, "");
if (name[0] == '\0') ... // name 可能是 NULL!
// 案例 2:靜默預設值失效
float angle = (float)tolua_tonumber(L, 1, 2*PI); // 傳 nil → angle=0,非 2π
// 字串:雙重檢查
const char* name = tolua_tostring(L, 1, "");
if (!name || name[0] == '\0') { /* 處理缺失/空字串 */ }
// 數值:型別檢查
lua_Number angle = 0;
if (lua_isnumber(L, 1)) angle = tolua_tonumber(L, 1, 2*PI);
else angle = 2*PI; // 明確預設
LUALIB_API lua_Number luaL_checknumber(lua_State* L, int narg) {
lua_Number d = lua_tonumber(L, narg);
if (d == 0 && !lua_isnumber(L, narg))
luaL_argerror(L, narg, LUA_TNUMBER); // 拋錯
return d;
}
Lua 內部存取越界會回傳 luaO_nilobject,配合 lua_is* 可完整判斷。
safe_tolua_tonumber 等安全包裝函式