向 lua 虚拟机传递信息(转自 云风的 BLOG )

转载 2006年06月04日 08:18:00

向 lua 虚拟机传递信息

当程序逻辑交给脚本跑了以后,C/C++ 层就只需要把必要的输入信息传入虚拟机就够了。当然,我们也需要一个高效的传递方法。

以向 lua 虚拟机传递鼠标坐标信息为例,我们容易想到的方法是,定义一个 C 函数 get_mouse_pos 。当 lua 脚本中需要取得鼠标坐标的时候,就可以调用这个函数。

但这并不是一个好方法,因为每次获取鼠标坐标,都需要在虚拟机和 native code 间做一次切换。我们应该寻求更高效的方案。

编写脚本的人可以只获取一次鼠标坐标,然后把数据放进一组全局变量。在一个运行片内,不再调用 get_mouse_pos 函数,而是通过访问全局变量来得到鼠标的位置。

从这个方案,我们可以引申开,其实这个全局变量可以由 C 程序主动设置,在 native code 的运行片中,Windows 消息处理完后,直接讲鼠标信息设入 lua 虚拟机。代码类似这样的。

lua_pushstring(L,"MOUSE_X");
lua_pushnumber(L,mouse_x);
lua_settable(L,LUA_GLOBALSINDEX);

lua_pushstring(L,"MOUSE_Y");
lua_pushnumber(L,mouse_y);
lua_settable(L,LUA_GLOBALSINDEX);

但是这里,依旧存在一个效率问题,那就是 lua_pushstring 。我们知道,lua 虚拟机中,每次产生一个 string ,都需要查对 string 在虚拟机中是否存在相同的拷贝,如果存在,就直接引用已有的;如果不存在,则产生一份新的拷贝。

这里,MOUSE_X 和 MOUSE_Y 两个 string 除了第一次运行,以后都是存在于 lua 虚拟机中的,虽然不会产生新的 string,但查找和比较字符串依然会消耗一定的时间。下面,我们来优化这个 lua_pushstring 操作。

我们可以在程序开始阶段,创建出这两个 string ,并且在 C 中保留引用。
lua_pushstring(L,"MOUSE_X");
_mouse_x_ref=lua_ref(L,-1);
lua_pushstring(L,"MOUSE_Y");
_mouse_y_ref=lua_ref(L,-1);

那么,以后运行时就不需要再做 lua_pushstring 操作了,而改成相对较快的 lua_getref 操作。

lua_getref(L,_mouse_x_ref);
lua_pushnumber(L,mouse_x);
lua_settable(L,LUA_GLOBALSINDEX);

lua_getref(L,_mouse_y_ref);
lua_pushnumber(L,mouse_y);
lua_settable(L,LUA_GLOBALSINDEX);

lua_getref 之所以相对快一些,是因为 lua 对数字做 key 的 table 操作有优化处理,直接变成一次指针操作。而 ref 就是记在一张全局表中的。而且 lua_getref 不需要 lua_pushstring 做过的 strcmp 操作。

那么这个方法还没有优化余地呢?答案还是有。

我们其实可以写一个 lua 程序,放在一个单独的文件(mouse.lua)中,程序很短:

return funtion(mx,my) MOUSE_X,MOUSE_Y=mx,my end

我们在程序启动的时候运行
lua_dofile(L,"mouse.lua");
_mouse_set_ref=lua_ref(L,-1);

那么,在设置鼠标坐标的时候就可以简单的做如下操作:
lua_getref(L,_mouse_set_ref);
lua_pushnumber(L,mouse_x);
lua_pushnumber(L,mouse_y);
lua_call(L,2,0);

这个方案只需要保留一个函数的 ref ,并且把设置的工作交给了虚拟机中的伪指令。单从这个例子(仅仅 MOUSE_X,MOUSE_Y两个需要传递的信息)来看,不能说明后者的效率更高一些,毕竟 lua_call 也有额外的消耗。但是,最后一个方案更加灵活,对于native code 向虚拟机更多数据的交换采用这种方案更加简洁。

ps. lua_ref 的东西,最后要记得调用 lua_unref 解引用。

向lua虚拟机传递信息

当程序逻辑交给脚本跑了以后,C/C++ 层就只需要把必要的输入信息传入虚拟机就够了。当然,我们也需要一个高效的传递方法。  以向 lua 虚拟机传递鼠标坐标信息为例,我们容易想到的方法是,定义一个 C...
  • blueboy2000
  • blueboy2000
  • 2010年04月01日 15:31
  • 1087

关于云风在 Lua 中实现面向对象的源码分析

①源码: local _class={}   function class(super) local class_type={} class_type.ctor=false class_t...
  • gh877916059
  • gh877916059
  • 2017年04月09日 15:19
  • 332

云风的博文《Lua C API 的正确用法》读后总结

云风的博文《Lua C API 的正确用法》(http://blog.codingnow.com/2015/05/lua_c_api.html) 该文章是一年前写的,不好意思在原文下面写心得体会了,...
  • oilcode
  • oilcode
  • 2016年04月07日 18:22
  • 907

协程(二) 云风coroutine源码分析

云风的coroutine代码量少、简洁,非常适合用来入门协程。从中我们可以学习到协程的设计思路,例如控制权的传递、调度器的设计、协程栈的使用等概念。...
  • u010599509
  • u010599509
  • 2016年08月29日 17:54
  • 1776

云风个人好书推荐 云风的blog:blog.codingnow.com

实用算法的分析与程序设计 吴文虎 王建德 编著 这是一本信息学奥赛的教材, 应该是先阶段能在书店里找到的最好的一本专门讲解程序设计算法的书. 可惜我当年竞赛的时候没有这么一本好书. 不仅讲解了很多的算...
  • sunwenjun
  • sunwenjun
  • 2008年05月06日 12:45
  • 3466

Lua 内存泄露

出自云风 blog 一个 Lua 内存泄露检查工具 昨天我们发现每日构建的服务器突然在一个晚上内存暴增了 8 G ,显然是发生了内存泄露。 之前,我们在 skynet 里留下...
  • haihsl123456789
  • haihsl123456789
  • 2015年01月15日 14:27
  • 802

研究下skynet,云风大神的开源框架

转载于 http://no001.blog.51cto.com/1142339/1354154 做游戏行业的大神众多。我是做应用server的,小打小闹,现在到处流行大数据,分布式。都是伪的...
  • u011676589
  • u011676589
  • 2015年04月08日 22:55
  • 1468

【Lua学习笔记】 Lua中实现面向对象,转自云风的博客

LuaOO 转自云风的博客:点击打开链接 local _class={} function class(super) local class_type={} class_type....
  • humanxing
  • humanxing
  • 2013年11月28日 09:39
  • 734

代码片段(云风的blog)

一个快速开方的函数: /* 来至 Quake 3 的源码 */ float CarmSqrt(float x){ union{ int intPart; float floatPart...
  • xdesigner
  • xdesigner
  • 2014年01月12日 17:53
  • 528

向虚拟机传递信息(非技术文章,中转专用)

sudo mount -t vboxsf  TDDOWNLOAD  /mnt/share/
  • baidang201
  • baidang201
  • 2013年01月15日 20:45
  • 334
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:向 lua 虚拟机传递信息(转自 云风的 BLOG )
举报原因:
原因补充:

(最多只允许输入30个字)