lua和C++交互的lua栈操作——以LuaTinker为例
2015-01-30 15:38
302 查看
一、
-- C++类注册函数(LuaTinker) 的lua栈操作:
-- C++类注册函数(LuaTinker),支持注册到命名空间namespace
二、
三、
--> 假设:meta_get函数执行到上面语句(栈内容如上) ——> t_meta[__index] == nil ——> 进入invoke_parent(L, func_name);
-- C++类注册函数(LuaTinker) 的lua栈操作:
-- lua栈内容(执行到pop语句) 栈地址 <--执行语句 space_name[name] = t1 -- (2b8) -- lua_rawset(L, -4); -- t1[__gc] = destroyer<T> -- (2d8) -- lua_rawset(L, -3); -- destroyer<T> -- (2f8) -- lua_pushcclosure(L, destroyer<T>, 0); -- __gc -- (2e8) -- lua_pushstring(L, "__gc"); -- t1[__newindex] = meta_set -- (2d8) -- lua_rawset(L, -3); -- meta_set -- (2f8) -- lua_pushcclosure(L, meta_set, 0); -- __newindex -- (2e8) -- lua_pushstring(L, "__newindex"); -- t1[__index] = meta_get -- (2d8) -- lua_rawset(L, -3); -- meta_get -- (2f8) -- lua_pushcclosure(L, meta_get, 0); -- __index -- (2e8) -- lua_pushstring(L, "__index"); -- t1[__name] = name -- (2d8) -- lua_rawset(L, -3); -- name -- (2f8) -- lua_pushstring(L, name); -- __name -- (2e8) -- lua_pushstring(L, "__name"); -- setmetatable(t1, t2) -- (2d8) -- lua_setmetatable(L, -2); -- t2[__index] = static_meta_get -- (2e8) -- lua_rawset(L, -3); -- static_meta_get -- (308) -- lua_pushcclosure(L, static_meta_get, 0); -- __index -- (2f8) -- lua_pushstring(L, "__index"); -- t2 -- (2e8) -- lua_newtable(L); -- t1 -- (2d8) -- lua_newtable(L); -- name -- (2c8) -- lua_pushstring(L, name); -- space_name[name] -- (2b8) -- lua_rawget(L, -2); -- name -- (2b8) -- lua_pushstring(L, name); space_name -- (2a8) -- push_meta(L, space_name::name); L -- (298) -- 初始状态
-- C++类注册函数(LuaTinker),支持注册到命名空间namespace
template<typename T> void class_addEx(lua_State* L, const char* name) { push_meta(L, space_name::name()); if(lua_istable(L, -1)) { class_name<T>::name(name); lua_pushstring(L, name); lua_rawget(L, -2); if (!lua_istable(L, -1)) { lua_pushstring(L, name); lua_newtable(L); lua_newtable(L); lua_pushstring(L, "__index"); lua_pushcclosure(L, static_meta_get, 0); lua_rawset(L, -3); lua_setmetatable(L, -2); lua_pushstring(L, "__name"); lua_pushstring(L, name); lua_rawset(L, -3); lua_pushstring(L, "__index"); lua_pushcclosure(L, meta_get, 0); lua_rawset(L, -3); lua_pushstring(L, "__newindex"); lua_pushcclosure(L, meta_set, 0); lua_rawset(L, -3); lua_pushstring(L, "__gc"); lua_pushcclosure(L, destroyer<T>, 0); lua_rawset(L, -3); lua_rawset(L, -4); } } lua_pop(L, 2); }
二、
-- meta_get栈操作如下: -- lua栈内容 栈地址 <--执行语句 t_meta[__index] -- (ed8) -- lua_rawget(L,-2); <-- 执行到此语句 -- __index -- (ed8) -- lua_pushvalue(L,2); t_meta -- (ec8) -- lua_getmetatable(L,1); __index -- (eb8) -- 初始 lua_pushstring(L, "__index"); t -- (ea8) -- 初始 L -- (e98) -- 初始状态
--// int lua_tinker::meta_get(lua_State *L) int lua_tinker::meta_get(lua_State *L) { lua_getmetatable(L,1); lua_pushvalue(L,2); lua_rawget(L,-2); bool is_dispatcher = false; const char* func_name = lua_tostring(L, 2); if(lua_isuserdata(L,-1)) { user2type<var_base*>::invoke(L,-1)->get(L); lua_remove(L, -2); } else if (lua_istable(L, -1)) { lua_remove(L, -1); is_dispatcher = true; } else if (lua_isnil(L, -1)) { lua_remove(L, -1); invoke_parent(L, func_name); if (lua_isnil(L, -1)) { lua_remove(L, -1); invoke_child(L, func_name); } if (lua_istable(L, -1)) { lua_remove(L, -1); is_dispatcher = true; } } //函数分发 if (is_dispatcher) { push_currfuncname(L, func_name); push_dispatcher(L); } lua_remove(L,-2); return 1; }
三、
--> 假设:meta_get函数执行到上面语句(栈内容如上) ——> t_meta[__index] == nil ——> 进入invoke_parent(L, func_name);
-- lua栈内容 栈地址 <--执行语句 tt[funcname] -- (e18) -- lua_remove(L, -2); -- tt[funcname] -- (e28) -- lua_rawget(L, -2); -->lua_istable(L, -1) || lua_isfunction(L, -1) -- funcname -- (e28) -- lua_pushstring(L, funcname); -- t_meta[__parent] = tt -- (e18) -- lua_rawget(L, -2); --> lua_istable(L,-1),重命名为tt -- __parent -- (e18) -- lua_pushstring(L, "__parent"); -- -- (e08) -- lua_remove(L, -1); -- t_meta[__index] -- (e18) -- lua_rawget(L,-2); t_meta -- (d08) -- lua_getmetatable(L,1); __index -- (cf8) -- 初始 lua_pushstring(L, "__index"); t -- (ce8) -- 初始 L -- (cd8) -- 初始状态(和上面的栈内容不匹配,因为是另一个过程,其满足t_meta[__index] == nil)
// static void invoke_parent(lua_State *L, const char* funcname) static void invoke_parent(lua_State *L, const char* funcname) { lua_pushstring(L, "__parent"); lua_rawget(L, -2); if(lua_istable(L,-1)) { lua_pushstring(L, funcname); lua_rawget(L, -2); if (lua_istable(L, -1) || lua_isfunction(L, -1)) { lua_remove(L, -2); } else { lua_remove(L, -1); invoke_parent(L, funcname); lua_remove(L, -2); } } }
相关文章推荐
- Lua和C++交互 学习记录之二:栈操作
- Lua和C++交互详细总结_2_堆栈的操作
- Lua与C++的交互的具体操作
- 【COCOS2DX-LUA 脚本开发之十一】C/C++与Lua之间进行数据函数交互 推荐
- C++与Lua交互(二)
- Lua与C/C++交互——Lua调用C/C++
- Lua与C/C++交互——C/C++调用Lua脚本
- C++与Lua互操作学习
- asp.net(C#)调用C++程序并交互操作【转】http://www.cnblogs.com/greatverve/archive/2010/06/07/Csharp-transfer-Cpp.html
- LuaOO (Lua与C++交互的面向对象封装)
- C++与Lua的交互(一)
- Lua与C/C++的交互4:往Lua中写入C/C++变量
- c++ 与 lua 简单交互1 (LUA CAPI)
- Lua与C/C++的交互5:C/C++调用Lua函数
- Lua与C/C++的交互6:Lua调用C/C++函数
- Lua与C/C++的交互1:C/C++与Lua最简单的互动
- c++与lua的交互--表的处理
- Lua与C++交互调用(1)
- C/C++与Lua交互(C实现的Lua编译器的例子)
- Lua与C/C++的交互3:C/C++中读取Lua文件中的表