对lua的简单扩展,使它能快速关联C++的数据。

很早的时候,我纠结过一件事,假如,我在C++公开给脚本的接口中,要使用C++里的某一个对象,并且,我的程序中有很多个不同的lua虚拟机,每一个虚拟机要关联一个C++对象,并且这是多线程的,那么这时候应该如何快速的利用lua_State指针来定位到对象指针呢?

以前我没有能力读懂lua的源码,也可以说不知道关键部分如何操作,我当时的做法,是利用临界区和std::map来解决问题的,很明显这个方式的效率很低很低。

现在有能力读lua源码了,当然有更有效的解决办法了,因为在我们利用lua的过程中,lua_State这个结构指针是要贯穿所有用到lua的地方的,那么我就可以对这个结构进行扩展,让它能够保存我的数据,只需要保存一个指针即可。

lua_State这个结构,定义在 lstate.h中   (lua.h中只是作者为了不让用户能够主动访问结构成员而定义的空结构指针,各种开源脚本引擎都是这样,为了安全性,大家懂的)

以lua5.2.3为例,该结构原始定义如下:

struct lua_State {

CommonHeader;

lu_byte status;

StkId top;  /* first free slot in the stack */

global_State *l_G;

CallInfo *ci;  /* call info for current function */

const Instruction *oldpc;  /* last pc traced */

StkId stack_last;  /* last free slot in the stack */

StkId stack;  /* stack base */

int stacksize;

unsigned short nny;  /* number of non-yieldable calls in stack */

unsigned short nCcalls;  /* number of nested C calls */

lu_byte hookmask;

lu_byte allowhook;

int basehookcount;

int hookcount;

lua_Hook hook;

GCObject *openupval;  /* list of open upvalues in this stack */

GCObject *gclist;

struct lua_longjmp *errorJmp;  /* current error recover point */

ptrdiff_t errfunc;  /* current error handling function (stack index) */

CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */

};

那么对这个结构扩展之后如下:

struct lua_State {

CommonHeader;

lu_byte status;

StkId top;  /* first free slot in the stack */

global_State *l_G;

CallInfo *ci;  /* call info for current function */

const Instruction *oldpc;  /* last pc traced */

StkId stack_last;  /* last free slot in the stack */

StkId stack;  /* stack base */

int stacksize;

unsigned short nny;  /* number of non-yieldable calls in stack */

unsigned short nCcalls;  /* number of nested C calls */

lu_byte hookmask;

lu_byte allowhook;

int basehookcount;

int hookcount;

lua_Hook hook;

GCObject *openupval;  /* list of open upvalues in this stack */

GCObject *gclist;

struct lua_longjmp *errorJmp;  /* current error recover point */

ptrdiff_t errfunc;  /* current error handling function (stack index) */

CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */

int __mydata;//这里

};

//同时增加两个lua接口,可以将函数接口放到lapi.c中,声明放到lua.h中即可,或者你是发烧追求极限效率不在乎更多的扩展和更新的朋友,那么你可以用硬编码定位,__mydata的偏移是0x70。

LUA_API void lua_setmydata(lua_State *L, int data){

L->__mydata = data;

}

LUA_API int lua_getmydata(lua_State *L){

return L->__mydata;

}

这样就万事具备了,重新编译lua,试试结果如何:

更抽象一点的做法:

使用硬编码进行定位:



对lua的简单扩展,使它能快速关联C++的数据。

时间: 2024-10-29 19:12:17

对lua的简单扩展,使它能快速关联C++的数据。的相关文章

Oracle根据【日期】组,其他条件根据PIVOT行转列。使每个日期条件关联的其他数据只有一行。

select OPER_TIME, MICROPAY, REFUND from ( select trunc(oper_time) oper_time, class_name, sum(total_fee) total_fee from wx_pay_detail group by trunc(oper_time),class_name ) pivot(sum(total_fee) for class_name in ('MicroPay'as "MICROPAY",'Refund'

简单扩展让beetl HTML标签支持父子嵌套

默认情况下,Beetl的html标签并不支持父子嵌套,就像类似jsp标签那样,父标签需要知道子标签的信息,子标签也需要知道父标签信息.但是beetl只需要简单扩展,就能完成嵌套标签支持. 首先看一个最终的使用效果,实现俩个html标签table.tag,tr.tag.可以在页面上这么用: <#table data ="${userList}"> <#tr class="3c" name="name"> 名称 </#t

递归扩展变量和简单扩展变量

1 递归扩展变量和简单扩展变量的区别 最大的区别在于,递归扩展变量等号右边的表达式里面的变量要等到该递归变量被用的时候再去扩展,而简单变量的话,在读取makefile的时候就已经扩展了. 并且简单扩展变量有前后关系,简单扩展变量只能用到在其前面定义的变量,而不能用到在其后面定义的变量.而递归扩展变量,要用的时候,需要扩展的时候,可以一直扩展到不能扩展为止,即递归扩展. 2 例子 foo := $(bar) bar = aaa all:;echo $(foo) 输出为空,因为在给foo赋值扩展等号

asp.net mvc Htmlhelper简单扩展

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace WebApplication1.MyHtmlHelper { public static class MyHtmlHelper { //页面渲染结果: //<span>我扩展的Label,自动生成Span标签</span> //把标签名都显示(直接将内

对bootstrap modal的简单扩展封装

对bootstrap modal的简单扩展封装 参考自:http://www.muzilei.com/archives/677   注:原文不支持bootstrap新版本,并且居中等存在问题 此段时间一直在学习bootstrap,主要是用于做后台,一直习惯用easyui,ui,jgrid前端框架,以至于并不习惯bootstrap的风格.近来考虑到easyui性能不太好,就用了bootstrap,先说下我所了解的bootstrap. 1.外国的框架用于显示中文看着总是不妥. 2.默认的样式觉得有些

简单扩展shiro 实现NOT、AND、OR权限验证(支持复杂一点的表达式)

简单扩展Shiro实现  类似organization:create OR organization:update OR organization:delete ( organization:create Or organization:update ) OR  NOT organization:delete ( organization:create && organization:update ) OR  ! organization:delete 其中操作符不限大小写,支持and.o

MVVM架构~knockoutjs系列之扩展ajax验证~验证输入数据是否与后台数据相等

返回目录 在看这篇文章之前,你有必要先看我之前的文章,之前文章是将一个方法以参数的形式传给KO,然后返回一个真假值,去做验证,这类似于面向对象语言里的委托,在JS里我们叫它回调方法,本篇文章与前一文章不同,需要有两个参数,其一是远程方法的签名(JS方法),其二是已知要比较的数据(可能是加密后的密码数据),当用户输入文字后,它将会调用JS方法获取远程数据,以比较原数据与你输入的数据是否匹配. 知识点:以对象作为参数进行传递 ko.validation.js的扩展 //ajax相等验证 kv.rul

使类的扩展更简单——扩展方法

1.什么是扩展方法? 扩展方法,首先是一种方法,它可以用来扩展已定义类型中的方法成员. 在扩展方法诞生之前,如果想为一个已有类型自定义含有特殊逻辑的新方法时,你必须重新定义一个类型来继承已有类型,以这种方式来添加方法.如果基类有抽象方法,则还要重新去实现这个抽象方法. 这样,为了扩展一个方法,需要承担更多的因继承而产生的开销.使用继承来扩展现有类型总有点大材小用的感觉,并且值类型或密封类(不能被继承的类)等也不能被继承,不能由此获得扩展. 于是,C#3.0提出了扩展方法. 2.扩展方法的使用 2

Log4net创建日志及简单扩展

1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是介绍如何在Visual Studio2008中使用log4net快速创建系统日志,如何扩展以输出自定义字段.2.一个简单的使用实例 第一步:在项目中添加对log4net.dll的引用,这里引用版本是1.2.10.0. 第二步:程序启动时读取log4net的配置文件. 如果是CS程序,在根目录的Program.cs中的Main