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 ...
随机推荐
- 一款仿ios7的switches开关按钮
今天给大家介绍一款仿ios7的switches开关按钮.这款按钮也是纯css实现的.无需引js代码.在实现中给出了两种颜色,三种不同大小的demo.一起看下效果图: 在线预览 源码下载 实现的代码 ...
- cocos2dx遇到的坑2
记录下在cocos2dx 2.x时代遇到的问题 1.cocos2dx retain 在onenter时,在onexit时 release 2.先结束定时器再退出界面 3.在不同帧里数据是有可能不一 ...
- [systemd]How To Use Systemctl to Manage Systemd Services and Units
转自: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services ...
- javascript那些不应该忽视的细节
1.null与Object.prototype使用typeof操作符结果都是object,但他们都不是Object的实例. typeof null // object null instanceof ...
- KafkaStream时间戳问题CreateTime = -1引起的程序中断
Exception in thread "app-8835188a-e0a0-46da-ac2a-6820ec197628-StreamThread-1" org.apache.k ...
- iOS边练边学--图片的拉伸
图片拉伸方法一: IOS 5.0以后才有的方法: - (void)viewDidLoad { [super viewDidLoad]; UIImageView *imageView = [[UIIma ...
- 微信小程序----map组件实现检索【定位位置】周边的POI
效果图 实现方法 地图采用微信小程序提供的map组件: 周边的数据坐标点通过高德地图提供的API接口,获取定位位置的周边或者指定位置周边的数据. WXML <view class="m ...
- rails局部模板 render
<%= render partial: 'file' %> file是以_开头命名的文件,比如_cart.html.erb 这样就可以用render来调用了 还可以传参数 比如 rails ...
- 5个界面效果很炫的JavaScript UI 框架
Web 开发很简单,Web 应用的 UI 开发却很复杂,如果能够利用一些成熟的 UI 框架可以大大的减少开发的复杂度.本文向你介绍 5 款界面效果很不错的 JS 框架. 1. ExtJS ExtJS ...
- 正则表达式”\d+\.?\d*”在匹配下列字符串时结果是失败的是?
A 12.5 B 1.25 C 以上都成功 D 以上都失败 解答:B \d+ 表示可以出现1次或是n次数字 \. .? 表示可以“.”可以出现一次,也可以不出现 \d* 表示可以出现0次或是n次数字