一、

-- 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, -))
{
class_name<T>::name(name); lua_pushstring(L, name);
lua_rawget(L, -);
if (!lua_istable(L, -))
{
lua_pushstring(L, name);
lua_newtable(L); lua_newtable(L);
lua_pushstring(L, "__index");
lua_pushcclosure(L, static_meta_get, );
lua_rawset(L, -);
lua_setmetatable(L, -); lua_pushstring(L, "__name");
lua_pushstring(L, name);
lua_rawset(L, -); lua_pushstring(L, "__index");
lua_pushcclosure(L, meta_get, );
lua_rawset(L, -); lua_pushstring(L, "__newindex");
lua_pushcclosure(L, meta_set, );
lua_rawset(L, -); lua_pushstring(L, "__gc");
lua_pushcclosure(L, destroyer<T>, );
lua_rawset(L, -); lua_rawset(L, -);
}
}
lua_pop(L, );
}

二、

-- 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,); lua_pushvalue(L,);
lua_rawget(L,-); bool is_dispatcher = false;
const char* func_name = lua_tostring(L, ); if(lua_isuserdata(L,-))
{
user2type<var_base*>::invoke(L,-)->get(L);
lua_remove(L, -);
}
else if (lua_istable(L, -))
{
lua_remove(L, -);
is_dispatcher = true;
}
else if (lua_isnil(L, -))
{
lua_remove(L, -);
invoke_parent(L, func_name);
if (lua_isnil(L, -))
{
lua_remove(L, -);
invoke_child(L, func_name);
}
if (lua_istable(L, -))
{
lua_remove(L, -);
is_dispatcher = true;
}
} //函数分发
if (is_dispatcher)
{
push_currfuncname(L, func_name); push_dispatcher(L);
} lua_remove(L,-); return ;
}

三、

--> 假设: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, -);
if(lua_istable(L,-))
{
lua_pushstring(L, funcname);
lua_rawget(L, -); if (lua_istable(L, -) || lua_isfunction(L, -))
{
lua_remove(L, -);
}
else
{
lua_remove(L, -);
invoke_parent(L, funcname);
lua_remove(L, -);
}
}
}

lua和C++交互的lua栈操作——以LuaTinker为例的更多相关文章

  1. Lua 和 C 交互中虚拟栈的操作

    Lua 和 C 交互中虚拟栈的操作 /* int lua_pcall(lua_State *L, int nargs, int nresults, int msgh) * 以保护模式调用具有" ...

  2. Lua和C++交互 学习记录之二:栈操作

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  3. Lua的栈及基本栈操作

    Lua的栈及基本栈操作 https://blog.csdn.net/mydriverc2/article/details/51134737 https://blog.csdn.net/mydriver ...

  4. Lua和C++交互详细总结

    转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信 ...

  5. Lua与C++交互初探之Lua调用C++

    Lua与C++交互初探之Lua调用C++ 上一篇我们已经成功将Lua的运行环境搭建了起来,也成功在C++里调用了Lua函数.今天我来讲解一下如何在Lua里调用C++函数. Lua作为一个轻量级脚本语言 ...

  6. 用好lua+unity,让性能飞起来——lua与c#交互篇

    前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...

  7. lua与C交互 具体

    什么样类型的函数可以被Lua调用 typedef int (*lua_CFunction) (lua_State *L); 符合类型的函数怎样处理后才可以被Lua调用 使用lua_register或者 ...

  8. Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...

  9. Lua和C++交互 学习记录之八:C++类注册为Lua模块

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

随机推荐

  1. tomcat8源码之架构解析

    Catalina:与开始/关闭shell脚本交互的主类,因此如果要研究启动和关闭的过程,就从这个类开始看起. Server:是整个Tomcat组件的容器,包含一个或多个Service. Service ...

  2. VBA学习笔记(4)--文件夹和文件遍历一层

    说明(2017.3.22): 1. '遍历指定文件夹里的文件 '遍历指定文件夹,返回第一层文件(不含文件夹) Public Sub test1() Dim k% Dim filename$ Dim p ...

  3. SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换

    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换 本文转载至:http://exceptioneye.iteye.com/blog/1698064 Spri ...

  4. 在XP系统下如何访问win10共享的打印机

    < > 找到 GUEST 用户,添加即可. 2. Win10 共享本地打印机 右击要共享的打印机,共享选项卡,设置共享名,这个共享很重要,要记住,尽量设置简单点.IP + 共享名就是网络打 ...

  5. Spring 4 官方文档学习(七)核心技术之Spring AOP APIs

    请忽略本篇内容!!! 1.介绍 2.Spring中的pointcut API 2.1.概念 2.2.对pointcut的操作 2.3. AspectJ expression pointcut 2.4. ...

  6. Spring bean的初始化及销毁

    Spring bean的几个属性:scope.init-method.destroy-method.depends-on等. Scope 在Spring容器中是指其创建的Bean对象相对于其他Bean ...

  7. nodejs基础 -- EventEmitter

    var events = require('events'); nodejs所有的异步I/O操作在完成时都会发送一个事件到事件队列 nodejs里面的许多对象都会分发事件,如: 一个net.Serve ...

  8. 【Java面试题】15 String s="Hello"; s=s+“world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?String与StringBuffer的超详细讲解!!!!!

    1.Java中哪些类是不能被继承的? 不能被继承的是那些用final关键字修饰的类.一般比较基本的类型或防止扩展类无意间破坏原来方法的实现的类型都应该是final的,在java中,System,Str ...

  9. 利用PHPExcel导出Excel相关设置

    功能包括: 1.设置单元格格式,包括单元格边框.单元格高度.单元格宽度 2.合并指定的单元格 3.设置Excel数据源,并将数据源保护起来(这个是为了实现单元格下拉选项功能) 4.设置字体样式 pub ...

  10. APACHE服务器500错误解决方法

    1.APACHE没开启rewrite模块. 解决办法:编辑apache的http.conf文件,找到#LoadModule rewrite_module modules/mod_rewrite.so, ...