精华内容
下载资源
问答
  • 云风 LUA源码赏析

    2018-03-16 23:31:02
    LUA源码分析 高清版,云风关于LUA源码的分析,非常精彩。
  • 云风lua源码欣赏

    2021-04-14 01:24:41
    【实例简介】这是云风写的,基于lua5.2版本源代码解析,希望加深lua学习的不要错过注这是这本书中其中部分章节的草稿。我不打算按顺序来编写这本书,而打算以独立章节的形式分开完成,到最后再做统一的调整。由丁业余...

    【实例简介】

    这是云风写的,基于lua5.2版本源代码解析,希望加深lua学习的不要错过

    这是这本书中其中部分章节的草稿。我不打算按顺序来编写这本书,而打算以独立章节的形式分开完成,

    到最后再做统一的调整。由丁业余时间不多,所以产出也不固定。

    l

    目录

    第一章概览

    口1源文件划分

    12代码风格

    L3Lua核心

    4代码翻译及预编译字节码

    15内嵌库

    4

    L6独立解析器及字节码编译器

    4

    了阅读源代码的次序

    第二章全局状态机及丙存管理

    2.1内存管理

    22全局状态机

    10

    2.2.1

    garbage colle

    12

    see

    13

    12.2.3 buff

    13

    2. 2.4 version.

    13

    22.5防止初始化的意外

    14

    第三章字符串

    17

    3,1数据结构

    17

    3.1.1 Ilash DoS

    18

    3.2实现

    20

    3:21字符串比较

    20

    32.2短字符串的内部化

    20

    3.3 U

    serrata

    的构造

    22

    第四章表

    25

    4.1数据结构

    25

    生2算洇

    27

    ,2,1短字符串优亿

    29

    匡2,2数字类型的哈希们

    31

    表的迭代

    44刈元方法的优化

    目录

    44.1类型名宇

    第五章函数与闭包

    39

    5,1数原型

    5.2 Pval

    41

    5.3闭包

    42

    5.31ua闭包

    43

    3.2C闭包

    53.3轻量C函数

    46

    俤第六章协程及函数的执行

    49

    6]栈与调用信息

    49

    6,11数据栈

    50

    612调用栈

    4

    63线程

    56

    62线程的执行与中炘

    8

    62.1异常处理

    622函数调用

    60

    623钩子

    624从C函数中挂起线程.,

    67

    625挂起与延线

    6.261acak和 lua-pcallk

    73

    627异常处理

    76

    第七章虚拟机

    77

    区1指令结构

    711常量

    7.1.2採作码分类校验

    79

    71.3操作码列表

    80

    2字节码的运行

    8⊥

    7.2.1 luan executel

    81

    72寄存器赋值

    83

    7.2.3表处理

    724表达式运算

    72.5分支和跳转

    7.2.6函数调用

    .,99

    727不定长参数

    101

    728生成闭包

    103

    72.9Por循环

    72,10协程的中断和延续

    108

    目录

    第八章内置库的实现

    111

    8.1_从πut模块看Lua的模块注册机制

    111

    区2math模块API的实现

    113

    8.3 string

    模坝

    115

    区.4暂且搁置

    6

    目录

    第一章概览

    Lua是一门编程语言,Lua官方网提供了由语言发明者实现的官方版朴虽然Lua有简洁清晰的语

    言标准,但我们不能将语言的标准制定和实现完全分开看待。事实上、随着官方实现版本的不断更新,Lua

    语言标准乜在不断变化

    本书试图向读者展现Iua官方实现的细节。在开始前,先从宏观上来看看,实现这门语言需要完成那些

    部分的上作

    Lua作为一门动态语言,提供了一个虚拟机。Lua代码最终都是是以字节码的形式由虚拟机解释执行的。

    把外部组织好的代码置入内存,让虚拟机解析运行,需要冇一个源代码解释器,或是预编译字节码的加载器。

    而只实现语言特性,几乎做不了什么事。所以Lua的官方版本还提供了一些库,并提供一系列CAPI,供

    第三方开发。这样,Iua就可以借助这些外部库,做一些我们需要的工作。

    下面,我们按这个划分来分拆解析。

    11源文件划分

    从官网下载到Lua52的源代码展开压缩包,会发现源代码文件全部放在sc子日录下。这些文件

    根据实现功能的不同,可以分为四部分团

    虚拟机运转的核心功能

    lapi. cC语言接口

    Ectype. c O标准库中 ctype相关实现

    Idebug. c Debug接口

    ldo.c函数调用以及栈管理

    Func. c函数原型及闭包管理

    lgc.c垃圾叵收

    memc内存管理接口

    object c对象操作的些函数

    opcodes. C虚拟机的字节码定义

    Istate. c全局状态机

    Ta是一个以 MiT license发布的开源项目,你可以自由的下载、传播、使用它,它的官方网站是:htp://w1a

    2Lua官方实现并不是对Lua语言的唯一实现。另外比较流行的Lua语言实现还有LuaI(htp:/w. wait

    由于采用了JI技

    术,运行性能更快。除此之外,还能在互联网上找到其它一些不同的实现。

    3本书讨论的Lua5.2.2版可以在http://www.lua.org/ftp/lua-5.2.2.tar

    g2下载获得

    4在Ludwik上有一篇文章介绍了La源代码的结构http://lua-users.org/wiki/luasource

    第一章概览

    string.c宇符串池

    Itable.c表类型的相关操作

    ltm.c元方法

    lvm.c虚拟机

    lzio.c输入流接口

    2.源代码解析以及预编译字节码

    Icode. c代码生成器

    Dump. c序列化预编译的Tna字节

    llex,C词法分析器

    lparser. c解析器

    lundump.c还原预编译的字节码

    3.内嵌库

    lauxlib. c库编写用到的辅助函数库

    lbaselib.c基础库

    Ibitlib.c位操作库

    Icorolib. c协程库

    Idblib c debug库

    linit.c内嵌库的初始化

    liolib c IO库

    Imathlib. c数学库

    loadlib. c动态扩展库管理

    loslib c OS

    Istrlib. c字符串库

    Itablib. c表处理库

    4.可执行的解析器,字节码编译器

    luac解释器

    luac. c字节码编译器

    1.2代码风格

    Lua使用 Clean c國巴编写的源代码模块划分清晰,大部分模块被分解在不同的c文件中实现,以同

    名的h文件描述模块导出的接口,比如, Istring. c实现了Lua虚拟机中字符串池的相关功能,而这部分的

    内部接口则在 Istring.h中描述。

    5 Clean c是标准C/C++的一个子集。它只包含了C话言中的一些必要特性。这样方便把La发布到更多的可能对C语言支持不完整的平台

    上。比如,对于没有 ctype.h的C语言编译环境,Lua提供∫ Ectype.c实现了一些兼容函数。

    【实例截图】

    【核心代码】

    展开全文
  • /* end sweep-string phase */ lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPCOST; } case GCSsweep: { lu_mem old = g->totalbytes; g->sweepgc = sweeplist(L, g->...

    GC 中最繁杂的 mark 部分已经谈完了。剩下的东西很简单。今天一次可以写完。

    sweep 分两个步骤,一个是清理字符串,另一个是清理其它对象。看代码,lgc.c 573 行:

      case GCSsweepstring: {
          lu_mem old = g->totalbytes;
          sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
          if (g->sweepstrgc >= g->strt.size)  /* nothing more to sweep? */
            g->gcstate = GCSsweep;  /* end sweep-string phase */
          lua_assert(old >= g->totalbytes);
          g->estimate -= old - g->totalbytes;
          return GCSWEEPCOST;
        }
        case GCSsweep: {
          lu_mem old = g->totalbytes;
          g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
          if (*g->sweepgc == NULL) {  /* nothing more to sweep? */
            checkSizes(L);
            g->gcstate = GCSfinalize;  /* end sweep phase */
          }
          lua_assert(old >= g->totalbytes);
          g->estimate -= old - g->totalbytes;
          return GCSWEEPMAX*GCSWEEPCOST;
        }

    在 GCSsweepstring 中,每步调用 sweepwholelist 清理 strt 这个 hash 表中的一列。理想状态下,所有的 string 都被 hash 散列开没有冲突,这每一列上有一个 string 。我们可以读读 lstring.c 的 68 行:

     if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
        luaS_resize(L, tb->size*2);  /* too crowded */

    当 hash 表中的 string 数量(nuse) 大于 hash 表的列数(size) 时,lua 将 hash 表的列数扩大一倍。就是按一列一个元素来估计的。

    值得一提的是,分布执行的 GC ,在这个阶段,string 对象是有可能清理不干净的。当 GCSsweepstring 步骤中,step 间若发生以上 string table 的 hash 表扩容事件,那么 string table 将被 rehash 。一些来不及清理的 string 很有可能被打乱放到已经通过 GCSsweepstring 的表列里。一旦发生这种情况,部分 string 对象则没有机会在当次 GC 流程中被重置为白色。在某些极端情况下,即使你调用 fullgc 一次也不能彻底的清除垃圾。

    关于 string 对象,还有个小地方需要了解。lua 是复用相同值的 TString 的,且同值 string 绝对不能有两份。而 GC 的分步执行,可能会导致一些待清理的 TString 又复活。所以在它在创建新的 TString 对象时做了检查,见 lstring.c 86 行:

     if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
          /* string may be dead */
          if (isdead(G(L), o)) changewhite(o);
          return ts;
        }

    相同的问题也存在于 upvalue 。同样有类似检查。

    此处 GCSWEEPCOST 应该是一个经验值。前面我们知道 singlestep 返回的这个步骤大致执行的时间。这样可以让 luaC_step 这个 api 每次执行的时间大致相同。mark 阶段是按扫描的字节数确定这个值的。而每次释放一个 string 的时间大致相等(和 string 的长度无关),GCSWEEPCOST 就是释放一个对象的开销了。

    GCSsweep 清理的是整个 GCObject 链表。这个链表很长,所以也是分段完成的。记录遍历位置的指针是 sweepgc ,每次遍历 GCSWEEPMAX 个。无论遍历是否清理,开销都是差不太多的。因为对于存活的对象,需要把颜色位重置;需要清理的对象则需要释放内存。每趟 GCSsweep 的开销势必比 GCSsweepstring 大。大致估算时间为 GCSWEEPMAX*GCSWEEPCOST 。

    真正的清理工作通过 lgc.c 408 行的 sweeplist 函数进行。

    static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
      GCObject *curr;
      global_State *g = G(L);
      int deadmask = otherwhite(g);
      while ((curr = *p) != NULL && count-- > 0) {
        if (curr->gch.tt == LUA_TTHREAD)  /* sweep open upvalues of each thread */
          sweepwholelist(L, &gco2th(curr)->openupval);
        if ((curr->gch.marked ^ WHITEBITS) & deadmask) {  /* not dead? */
          lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
          makewhite(g, curr);  /* make it white (for next cycle) */
          p = &curr->gch.next;
        }
        else {  /* must erase `curr' */
          lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
          *p = curr->gch.next;
          if (curr == g->rootgc)  /* is the first element of the list? */
            g->rootgc = curr->gch.next;  /* adjust first */
          freeobj(L, curr);
        }
      }
      return p;
    }

    后半段比较好理解,当对象存活的时候,调用 makewhite ;死掉则调用 freeobj 。sweeplist 的起点并不是从 rootgc 而是 sweepgc (它们的值可能相同),所以对于头节点,需要做一点调整。

    前面的 sweep open upvalues of each thread 需要做一点解释。为什么 upvalues 需要单独清理?这要从 upvalue 的储存说起。

    upvalues 并不是放在整个 GCObject 链表中的。而是存在于每个 thread 自己的 L 中(openupval 域)。为何要这样设计?因为和 string table 类似,upvalues 需要唯一性,即引用相同变量的对象只有一个。所以运行时需要对当前 thread 的已有 upvalues 进行遍历。Lua 为了节省内存,并没有为 upvalues 多申请一个指针放置额外的链表。就借用 GCObject 本身的单向链表。所以每个 thread 拥有的 upvalues 就自成一链了。相关代码可以参考 lfunc.c 53 行处的 luaF_findupval 函数。

    但也不是所有 upvalues 都是这样存放的。closed upvalue 就不再需要存在于 thread 的链表中。在 luaF_close 函数中将把它移到其它 GCObject 链中。见 lfunc.c 106 行:

      unlinkupval(uv);
          setobj(L, &uv->u.value, uv->v);
          uv->v = &uv->u.value;  /* now current value lives here */
          luaC_linkupval(L, uv);  /* link upvalue into `gcroot' list */

    另,某些 upvalue 天生就是 closed 的。它们可以直接通过 luaF_newupval 构造出来。

    按道理来说,对 openvalues 的清理会增加单次 **sweeplist 的负荷,当记入 singlestep 的返回值。但这样会导致 sweeplist 接口变复杂,实现的代价也会增加。鉴于 thread 通常不多,GC 开销也只是一个估算值,也就没有特殊处理了。


    GC 的最后一个流程为 GCSfinalize 。

    它通过 GCTM 函数,每次调用一个需要回收的 userdata 的 gc 元方法。见 lgc.c 的 446 行:

    static void GCTM (lua_State *L) {
      global_State *g = G(L);
      GCObject *o = g->tmudata->gch.next;  /* get first element */
      Udata *udata = rawgco2u(o);
      const TValue *tm;
      /* remove udata from `tmudata' */
      if (o == g->tmudata)  /* last element? */
        g->tmudata = NULL;
      else
        g->tmudata->gch.next = udata->uv.next;
      udata->uv.next = g->mainthread->next;  /* return it to `root' list */
      g->mainthread->next = o;
      makewhite(g, o);
      tm = fasttm(L, udata->uv.metatable, TM_GC);
      if (tm != NULL) {
        lu_byte oldah = L->allowhook;
        lu_mem oldt = g->GCthreshold;
        L->allowhook = 0;  /* stop debug hooks during GC tag method */
        g->GCthreshold = 2*g->totalbytes;  /* avoid GC steps */
        setobj2s(L, L->top, tm);
        setuvalue(L, L->top+1, udata);
        L->top += 2;
        luaD_call(L, L->top - 2, 0);
        L->allowhook = oldah;  /* restore hooks */
        g->GCthreshold = oldt;  /* restore threshold */
      }
    }

    代码逻辑很清晰。需要留意的是,gc 元方法里应避免再触发 GC 。所以这里采用修改 GCthreshold 为比较较大值来回避。这其实不能完全避免 GC 的重入。甚至用户错误的编写代码也可能主动触发,但通常问题不大。因为最坏情况也只是把 GCthreshold 设置为一个不太正确的值,并不会引起逻辑上的错误。

    后记:

    终于把这个系列写完了。接下来的工作,我想做一些分析,看能否以最小代价(尽量少用锁)改造出一个多线程版本的 GC 。

    展开全文
  • 云风此人,我从未见过,但是游戏界,他的传闻还是很多的,这个是他对于lua这个脚本语言的一个原理分析,我受益良多。
  • programming in lua 4th,lua程序设计第4版,我学第一版的时候是200多页,现在2016年出的第四版还是200多页,更新了一些内容。还有国内大神云峰编写的《lua源码鉴赏》,分享出来一块学习进步吧。
  • 云风lua面向对象代码解析

    千次阅读 2019-11-26 14:54:05
    云风lua面向对象 云风wiki: https://blog.codingnow.com/cloud/LuaOO local _class={} function class(super) local class_type = {} class_type.ctor = false class_type.super = super class_type.new=...


    一. 云风lua面向对象

    云风wiki: https://blog.codingnow.com/cloud/LuaOO

    local _class={}
     
    function class(super)
    	local class_type = {}
    	class_type.ctor = false
    	class_type.super = super
    	class_type.new=function(...) 
    			local obj={}
    			do
    				local create
    				create = function(c,...)
    					if c.super then
    						create(c.super,...)
    					end
    					if c.ctor then
    						c.ctor(obj,...)
    					end
    				end
     
    				create(class_type,...)
    			end
    			setmetatable(obj,{ __index=_class[class_type] })
    			return obj
    		end
    	local vtbl={}
    	_class[class_type]=vtbl
     
    	setmetatable(class_type,{__newindex=
    		function(t,k,v)
    			vtbl[k]=v
    		end
    	})
     
    	if super then
    		setmetatable(vtbl,{__index=
    			function(t,k)
    				local ret=_class[super][k]
    				vtbl[k]=ret
    				return ret
    			end
    		})
    	end
     
    	return class_type
    end
    

    类定义

    base_type = class()		-- 定义一个基类 base_type
     
    function base_type:ctor(x)	-- 定义 base_type 的构造函数
    	print("base_type ctor")
    	self.x=x
    end
     
    function base_type:print_x()	-- 定义一个成员函数 base_type:print_x
    	print(self.x)
    end
     
    function base_type:hello()	-- 定义另一个成员函数 base_type:hello
    	print("hello base_type")
    end
    
    test=class(base_type)	-- 定义一个类 test 继承于 base_type
     
    function test:ctor()	-- 定义 test 的构造函数
    	print("test ctor")
    end
     
    function test:hello()	-- 重载 base_type:hello 为 test:hello
    	print("hello test")
    end
    

    类使用

    a = test.new(1)	-- 输出两行,base_type ctor 和 test ctor 。这个对象被正确的构造了。
    a:print_x()	-- 输出 1 ,这个是基类 base_type 中的成员函数。
    a:hello()	-- 输出 hello test ,这个函数被重载了。
    

    二. 知识点

    1. __index

    __index用于查询,当取一个table的不存在的字段时会触发,可以帮助我们解决table中字段的默认值问题。
    如果要继承某个模块,使用

    setmetatable(obj, {__index = XXX})
    

    XXXX为希望继承的模块名。

    2. __newindex

    __newindex用于更新,比如监测给table中不存在的字段的赋值。
    __newindex元方法被调用的时候会传入3个参数:table本身、字段名、想要赋予的值。

    setmetatable(obj, { __newindex = 
        function(t, k, v) 
           -- TODO
        end
        })
    

    接下来我们来解析一下上面云风大神的lua代码

    三. 代码解析

    -- _class用来保存所有类模板
    local _class = {}
    
    -- 此方法用于定义类,super为基类
    function class(super)
    	-- class_type 可以理解为类模板
    	local class_type = {}
    	-- ctor为构造函数
    	class_type.ctor = false
    	-- 赋值基类
    	class_type.super = super
    	-- 定义new成员方法
    	class_type.new = function(...) 
    			local obj = {}
    			do
    			    -- create 用于实现嵌套调用,目的是调用基类的ctor函数,即基类的构造函数
    				local create
    				create = function(c,...)
    					if c.super then
    					   -- 如果有基类,优先调用基类的ctor函数
    						create(c.super, ...)
    					end
    					if c.ctor then
    						-- 调用构造函数
    						c.ctor(obj, ...)
    					end
    				end
     
    				create(class_type, ...)
    			end
    			-- obj继承_class[class_type],其实就是下面的vtbl,obj就是类对象
    			setmetatable(obj, { __index = _class[class_type] })
    			-- new方法返回obj对象
    			return obj
    		end
    		
    	-- vtbl可以理解为类容器
    	local vtbl = {}
    	_class[class_type] = vtbl
    	
        -- class_type 新增成员的时候,存到vtbl中
    	setmetatable(class_type, { __newindex=
    		function(t, k, v)
    			vtbl[k] = v
    		end
    	})
     
    	if super then
    	    -- 如果有基类,取某个成员的时候,先从_class中找到基类容器,然后从基类容器中取成员赋值给vtbl
    	    -- 意思就是,如果子类有成员,则直接调用,否则从基类中找成员调用
    		setmetatable(vtbl, { __index = 
    			function(t, k)
    				local ret = _class[super][k]
    				vtbl[k] = ret
    				return ret
    			end
    		})
    	end
     
        -- 返回类模板,可以添加ctor函数,可以添加成员函数,这些都会被加到vtbl中,
        -- 当执行new方法的时候,就会执行vtbl的ctor函数,返回obj
        -- 执行成员方法的时候,就会执行obj的成员方法,因为obj继承了vtbl,所以会执行vtbl的成员方法
        -- 如果vtbl没有成员方法,则从其基类中查找
    	return class_type
    end
    
    展开全文
  • OSTC开源技术大会分会场三:简悦科技 CTO云风,演讲主题《基于Lua开发网络游戏》
  • 云风写的Lua源码欣赏,基于lua5.2版本源代码解析,对于初初学习lua语言的有很不错的帮助
  • 这个是云风大侠翻译的 Lua5.1 参考手册 翻译在云风个人网站上,地址为http://www.codingnow.com/2000/download/lua_manual.html#pdf-require 并非全部翻译,但是前面的大部分和重点都翻译,真的很有用,所以转换成...
  • lua 5.3 手册 中文版 完整版
  • 因为有别的现有架构,所以只是换lua中间件,同时需要protobuf,所以使用pbc加入编译。tolua#在github上就有simpleframwork可用,个人项目可以使用。 下载tolua# 的runtime项目...

    记录以备忘

    因为有别的现有架构,所以只是换lua中间件,同时需要protobuf,所以使用pbc加入编译。tolua#在github上就有simpleframwork可用,个人项目可以使用。

    1. 下载tolua# 的runtime项目 https://github.com/topameng/tolua.git到D:/tolua#
    2. 下载luapbc 项目https://github.com/cloudwu/pbc.git到D:/tolua#/pbc

      此时tolua#项目结构为

    3. 修改编译脚本
    #!/bin/bash
    # 32 Bit Version
    mkdir -p window/x86
    # mingw32-make = 'C:\Ruby\DevKit\mingw\bin\mingw32-make.exe'
    cd luajit
    mingw32-make clean
    
    mingw32-make BUILDMODE=static CC="gcc -m32 -O3"
    cp src/libluajit.a ../window/x86/libluajit.a
    mingw32-make clean
    cd ..
    
    # build protobuf fengyun ban pbc from https://github.com/cloudwu/pbc/
    cd pbc
    mingw32-make lib BUILDMODE=static CC="gcc -m32 -O3"
    cp build/libpbc.a ../window/x86/libpbc.a
    mingw32-make clean
    cd ..
    
    gcc -m32 -O3 -std=gnu99 -shared \
        int64.c \
        uint64.c \
        tolua.c \
        pb.c \
        lpeg.c \
        struct.c \
        cjson/strbuf.c \
        cjson/lua_cjson.c \
        cjson/fpconv.c \
        luasocket/auxiliar.c \
        luasocket/buffer.c \
        luasocket/except.c \
        luasocket/inet.c \
        luasocket/io.c \
        luasocket/luasocket.c \
        luasocket/mime.c \
        luasocket/options.c \
        luasocket/select.c \
        luasocket/tcp.c \
        luasocket/timeout.c \
        luasocket/udp.c \
        luasocket/wsocket.c \
        luasocket/compat.c \ 
        pbc/binding/lua/pbc-lua.c \ 
        -o Plugins/x86/tolua.dll \
        -I./ \
        -Iluajit/src \
        -Ipbc \ 
        -Ipbc/src \
        -Icjson \
        -Iluasocket \
        -lws2_32 \
        -Wl,--whole-archive window/x86/libluajit.a window/x86/libpbc.a -Wl,--no-whole-archive -static-libgcc

    这是修改好的win32平台编译脚本,修改了几个内容如下:

    ....
    # 新加,编译pbc.a
    # build protobuf fengyun ban pbc from https://github.com/cloudwu/pbc/
    cd pbc
    mingw32-make lib BUILDMODE=static CC="gcc -m32 -O3"
    cp build/libpbc.a ../window/x86/libpbc.a
    mingw32-make clean
    cd .. 

    gcc -m32 -O3 -std=gnu99 -shared \
       ... 

        pbc/binding/lua/pbc-lua.c \ # 新加,要编译c代码,另一个是lua-53没用到
        -o Plugins/x86/tolua.dll \
        ...
        -Ipbc \ # 新加,   头文件目录
        -Ipbc/src \# 新加,头文件目录 

        ...

        -Wl,--whole-archive window/x86/libluajit.a window/x86/libpbc.a -Wl,--no-whole-archive -static-libgcc

    把生成的libpbc.a包含到dll中。

    4.修改代码文件

    pbc/binding/lua/pbc-lua.c 这个文件需要改一下
    把 20行
    #ifndef _MSC_VER
    改成
    #if !defined( _MSC_VER ) && !defined( __MINGW32__ ) && !defined( __MINGW64__)

    因为我用的mingw + msys编译的,mingw没有_MSC_VER 这个定义,所以只好加mingw自己的

    5.编译,运行mingw的msys.bat,在弹出的shell窗口cd到tolua#目录,运行./build_win32.sh生成tolua.dll在plugins/x86/目录下,拷贝到项目plugins/x86就好了。

    6.使用

    1. 复制生成的dll文件到使用tolua#的unity项目plugins/x84或x86_64下,
    2. 修改luadll.cs,添加c接口,在适当的位置如下写

            /*

            ** third party library
            */
            
            [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
            public static extern int luaopen_protobuf_c(IntPtr L);

            3.启动lua时注册proto库, 

            luaState.OpenLibs(LuaDLL.luaopen_pb);
            luaState.OpenLibs(LuaDLL.luaopen_struct);
            luaState.OpenLibs(LuaDLL.luaopen_lpeg);
            #if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
            luaState.OpenLibs(LuaDLL.luaopen_bit);
            //lua.OpenLibs(LuaDLL.luaopen_bit);
            #endif 
            //luaState.OpenLibs(LuaDLL.luaopen_sproto_core);
            luaState.OpenLibs(LuaDLL.luaopen_protobuf_c);

            就和lua注册别的第三方库一样,找到然后把proto的注册调用加上,就可以写lua代码了,参考pbc自带的demo


         

     

    注:

    tolua#项目地址https://github.com/topameng/tolua

    如果没装mingwin的话可以下载tdm-gcc,在SourceForge搜tdm mingw就有http://jaist.dl.sourceforge.net/project/tdm-gcc/TDM-GCC%20Installer/tdm64-gcc-5.1.0-2.exe

    安装64位版的,因为也要编译64位dll。

    安装方法:

    1,运行安装文件,目录选择d:/mingw(自定义)

    2,mingw安装到d:/mingw.配置bin目录到path环境变量。

    3,下载msys,解压或安装(可以是执行文件和压缩包文件)到d:msys(自定义)https://sourceforge.net/projects/mingwbuilds/files/external-binary-packages/

    4,修改msys目录下msys.bat,在第一行之前加入call "D:\Development\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"(vs2015的环境变量脚本,根据安装的vs来写,或者不加)

    5,修改关联文件,d:msys/etc/fstab文件,可安装fstab.sample修改,即关联mingw所在安装目录,大致内容为:

    #Win32_Path        Mount_Point
    D:/MinGW             /mingw

    6,基本完成了,执行msys.bat在弹出的shell窗口可以导航到tolua#进行编译了。

    展开全文
  • Lua 5.3 参考手册(云风)

    2018-02-10 11:53:53
    Lua 5.3 参考手册 作者 Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes 译者 云风 制作 Kavcc
  • Lua5.3云风

    2017-01-07 22:41:21
    http://cloudwu.github.io/lua53doc/manual.html#2.1
  • 我的cocos2d-x-3.2集成云风pbc lua binding方法 八月 19, 2014 | Posted by K-Res 关于protobuf的cocos2d-x lua的集成,参考过网上的一些资料,考虑过用google官方实现,但感觉过于臃肿,且没有直接的lua接口,...
  • 以上是基本的 class 定义的语法,完全兼容 lua 的编程习惯。我增加了一个叫做 ctor 的词,作为构造函数的名字。 下面看看怎样继承: test = class ( base_type ) -- 定义一个类 test 继承于 base_type   ...
  • 云风的 BLOG- 采访 Lua 发明人的一篇文章,Lua 的设计理念
  • lua里实现table的序列化和反序列化

    千次阅读 2017-07-16 20:59:20
    感谢原作者辛勤整理:Lua table的序列化和反序列化 --------------table转字符串(只取标准写法,以防止因系统的遍历次序导致ID乱序) function sz_T2S(_t) local szRet = "{" function doT2S(_i, ...
  • lua源码鉴赏云风

    2015-11-07 09:49:53
    云风写的,讲了一些实现的细节,适合想要深入的朋友,分就不要了,没分的也可以下
  • lua gc 优化方案

    千次阅读 2015-05-11 18:01:42
    此文章至少适合lua5.1 在我的项目中,变量增减多了,就...解决方案有两种,一种是云风给出的多线程gc 还有一种则是我正在用的,在不能修改lua引擎代码的情况(比如使用Bolt界面引擎)能很好发挥作用的方案: 我称此
  • Lua源码欣赏2012年11月-云风.pdf
  • 会让你惊讶的是,在面向对象概念已经泛滥的今天,lua作为新兴脚本语言其甚至没有原生态的提供对面向对象的支持,说简单点是lua没有class相关的关键字,其也不支持定义一个类,更别提多态了。  不过读者肯定注意...
  • Lua面向对象设计中添加super

    万次阅读 2012-01-12 15:29:06
    云风lua oo 实现方法 http://blog.codingnow.com/2006/06/oo_lua.html 无法在子类的函数中使用super:xxx 调用父类的函数。 1.直接用父类调用 base_type=class() -- 定义一个基类 base_type function...
  • lua源码导读---云风

    热门讨论 2012-12-13 13:54:43
    云风新作-----lua源码导读。目前网上最好的lua源代码阅读教程。帮助你快速理解lua实现原理。
  • VS2015编译 Lua源码

    2019-01-10 10:22:37
    Lua作为一门热门的脚本语言, 在游戏,程序热更新等领域使用很广,Lua的解释器是用C语言写的,源码不过一万多行。作为程序员,详细学习一门语言的源码是很有必要的,可以说Lua的源码,是程序员最容易掌握的,不像JVM...
  • 研究下skynet,云风大神的开源框架

    千次阅读 2015-04-08 22:55:49
    做游戏行业的大神众多。我是做应用server的,小打小闹,现在到处流行大数据,分布式。都是伪的。。做应用服务器开发的大神,没听说多。做webserver的一大堆电商。...基本上都是从做游戏架构等...skynet是云风用c和
  • 一、table的解释(云风说的很好,摘抄如下):  lua 的整体效率是很高的,其中,它的 table 实现的很巧妙为这个效率贡献很大。 lua 的 table 充当了数组和映射表的双重功能,所以在实现时就考虑了这些...
  • Commentsdouble占8个字节,在32位机器上可以用一个特殊的double来编码其它的TValuehttp://hi.baidu....采用RB的虚拟机,编译的工作量是大一些,主要原因是虚拟寄存器的合理分配,云风以前好像也指出过。要实...
  • Lua 5.3中文参考手册(有标签)云风译。有标签看起来更加方便。函数按照字母索引加了标签。存一份手册在电脑,常翻常新
  • 转自:http://blog.codingnow.com/cloud/LuaApiCall#include "lua.h"#include <malloc.h>#include <windows.h>   typedefvoid* (__stdcall *func_call)();... func_call fc=(func_call)lua_touserdata
  • 先上代码 function luautil.serialize(t, sort_parent, sort_child) local mark={} local assign={} local function ser_...2、添加了writefile函数,因为lua的文件写入有最大字节数限制,所以一行一行写入。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,071
精华内容 828
关键字:

云风lua