lua和C++交互的lua栈操作——以LuaTinker为例
一、
-- 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为例的更多相关文章
- Lua 和 C 交互中虚拟栈的操作
Lua 和 C 交互中虚拟栈的操作 /* int lua_pcall(lua_State *L, int nargs, int nresults, int msgh) * 以保护模式调用具有" ...
- Lua和C++交互 学习记录之二:栈操作
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
- Lua的栈及基本栈操作
Lua的栈及基本栈操作 https://blog.csdn.net/mydriverc2/article/details/51134737 https://blog.csdn.net/mydriver ...
- Lua和C++交互详细总结
转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信 ...
- Lua与C++交互初探之Lua调用C++
Lua与C++交互初探之Lua调用C++ 上一篇我们已经成功将Lua的运行环境搭建了起来,也成功在C++里调用了Lua函数.今天我来讲解一下如何在Lua里调用C++函数. Lua作为一个轻量级脚本语言 ...
- 用好lua+unity,让性能飞起来——lua与c#交互篇
前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...
- lua与C交互 具体
什么样类型的函数可以被Lua调用 typedef int (*lua_CFunction) (lua_State *L); 符合类型的函数怎样处理后才可以被Lua调用 使用lua_register或者 ...
- Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...
- Lua和C++交互 学习记录之八:C++类注册为Lua模块
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
随机推荐
- iOS播放系统声音和震动
在需要声音的类的.h文件中添加 #import <AudioToolbox/AudioToolbox.h>static SystemSoundID shake_sound_male ...
- 【WPF】设置TextBox内容为空时的提示文字
<TextBox Width="150" Margin="5"> <TextBox.Resources> <VisualBrush ...
- vue项目引入社交分享插件
vshare 基于百度分享开发的支持VUE2.X的分享插件,为您带来更多的流量!提供多种风格按钮,代码加载更快,引入社会化流量,提升网页抓取速度等优点.github地址:https://github. ...
- openwrt内核配置选项添加
摘自:http://blog.csdn.net/weiniliuchao/article/details/50295527 增加内核配置选项 openwrt的.config文件中,关于内核的选项都是形 ...
- jffs2系统制作2
http://blog.chinaunix.net/uid-23208702-id-353022.html 1.2. 安装zlib库 由于交叉编译mtd工具时需要zlib.h文件,所以在编译之前先 ...
- RESTful测试工具-RESTClient
很多测试人可能对RESTful的概念还是很模糊的,那么到底什么是RESTful?百度百科给出的一句话描述是一个架构样式的网络系统,似乎还是有点不懂?OK,说到Restful,我们一般从REST开始说起 ...
- day day up
复位与时钟控制器 RCC(Reset Clock Controller) 通用输入输出 GPIO(General Purpose Input/Output) 嵌套向量中断控制器 NVIC(Nested ...
- Uncaught (in promise) Provided element is not within a Document
今天在使用html2canvas生成海报的时候,发现报了个如下图所示的错误: 发生这个错误的本质原因是在调用html2canvas的时候传递的是jQuery对象,而不是DOM原生对象. 开始的时候我是 ...
- 关于MyEclipse项目的名字的修改对项目导入导出的影响
不要修改项目名字,不管是在MyEclipse中(.project文件里面的额name会变)还是在G:\MyEclipseData目录下(.project文件里面的额name不会变),否则导入的时候不能 ...
- 关于Cocos2d-x中监听物体不超越边界的解决方案
写一个监听器 touchlistener->onTouchMoved = [this](Touch* pTouch, Event*) { auto delta = pTouch->getD ...