Lua简介

luawiki  中文  官方社区:lua-users)是一门开源、简明、可扩展且高效的弱类型解释型脚本语言。

由于其实现遵循C标准,它几乎能在所有的平台(windows、linux、OS X、Android、iOS、PlayStation、XBox、wii等)上运行。

当前最新的lua版本为5.3.5;前两位版本号为lua的大版本,相同的大版本之间是兼容的;即5.3.5向下兼容5.3.4~0等版本

版本信息定义在lua.h中,即宏LUA_RELEASE

#define LUA_VERSION_MAJOR    "5"
#define LUA_VERSION_MINOR    "3"
#define LUA_VERSION_NUM        503
#define LUA_VERSION_RELEASE    "4"

#define LUA_VERSION    "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE    LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_COPYRIGHT    LUA_RELEASE "  Copyright (C) 1994-2017 Lua.org, PUC-Rio"
#define LUA_AUTHORS    "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"

lua非常小巧精简,其解释器加上周边的库函数也不过1w多行代码。以下是Lua5.3.5的源文件:

核心文件:

文件名 作用 对外接口前缀
lapi.c c语言接口 lua_
lcode.c 源码生成器 luaK_
ldebug.c 调试库 luaG_
ldo.c 函数调用及栈管理 luaD_
ldump.c 序列化预编译的lua字节码  
lfunc.c 提供操作函数原型及闭包的辅助函数 luaF_
lgc.c GC luaC_
llex.c 词法分析 luaX_
lmem.c 内存管理 luaM_
lobject.c 对象管理 luaO_
lopcodes.c 字节码操作 luaP_
lparser.c 语法分析 luaY_
lstate.c 全局状态机 luaE_
lstring.c 字符串操作 luaS_
ltable.c 表操作 luaH_
ltm.c tag方法 luaT_
lundump.c 加载预编译字节码 luaU_
lvm.c 虚拟机 luaV_
lzio.c 缓存流接口 luaZ_

内嵌库文件: 

文件名 作用
lauxlib.c 库编写时需要用到的辅助函数库
lbaselib.c 基础库
lbitlib.c bit位操作库
lcorolib.c 协程库
lctype.c 封装c标准库中的ctype文件
ldblib.c 调试库
linit.c 负责内嵌库的初始化
liolib.c IO库
lmathlib.c 数学库
loadlib.c 动态扩展库加载器
loslib.c OS库
lstrlib.c 字符串操作库
ltablib.c 表操作库
lutf8lib.c utf8库

解释器、编译器文件:

文件名 作用
lua.c 解释器
luac.c 编译器

lua很容易编译成静态库、动态库或以源代码的形式集成到应用程序中,并方便地与c/c++及其他语言进行互操作,因此其被称为胶水语言(glue language)。

如果不想自己编译lua,可从LuaBinaries下载编译好的各个平台上静态库、动态库及基于这些库实现的lua、wlua解释器、luac编译器等工具.。

由于其动态性,支持热更,上手难度低等特点,在游戏行业常常被用来开发业务逻辑。

可使用跨平台vsCode来编辑和调试lua脚本(注:调试需要安装actboy168的LuaDebug插件  其github在这里,可在vscode的Extensions面板中搜索lua找到它然后直接安装)。

腾讯也提供了一款vsCode的lua调试器插件:LuaPanda 其github在这里

lua/wlua解释器

lua.exe、wlua.exe解释器都可以通过传入lua文件,来执行lua脚本  如:lua.exe/wlua.exe  D:/LuaTest/test1.lua  // 将Hello World!字符串打印到控制台和写入到e:/test.txt文件中

D:/LuaTest/test1.lua内容如下:

print("Hello World!")

file = io.open("e:/test.txt", "w")
file:write("Hello World!", "
")
file:close()

lua.exe是subsystem:console类型程序,可在控制台交互式地接受用户的输入,并能使用print等函数将结果输出到控制台中

wlua.exe是subsystem:windows类型程序,无控制台窗口,因此不能将结果输出到控制台中,但可输出到文件;另外通过加载GUI dll插件模块,可使用模块中的接口来创建窗口程序

在lua5.1.5及之前版本,luaforwindowsgooglecode上的站点)项目会集成lua在windows上的各个插件,方便大家在windows上使用lua,如今该项目已停更

如:在luaforwindows中就集成了alien插件,该插件中提供的lua版的windows api,配合wlua.exe来运行以下脚本

require "alien"

local MessageBox = alien.User32.MessageBoxA
MessageBox:types{ret = "long", abi = "stdcall", "long", "string", "string", "long" }
MessageBox(0, "Hello World!", "My Window Title", 0x00000040)

lua.exe命令行

lua.exe –help // 查看lua.exe的用法

lua.exe -v // 显示出Lua版本号   Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio

lua.exe  // 进入交互模式  windows系统按Ctrl+C、linux系统按Ctrl+D可退出交互模式

lua.exe –  // 从标准设备读入脚本,输完后按回车,然后按Ctrl+Z并回车,会执行输入内容 注:进入输入模式后可按Ctrl+C强制退出

lua.exe e:LuaTest.lua  // 加载并执行e:LuaTest.lua

lua.exe -e “print(type(100))”  // 通过-e参数执行一段lua代码

注:对于5.3版本的Lua,lua.exe在开始执行前,会读取环境变量LUA_INIT_5_3的值,若其没定义,则会尝试另外一个环境变量LUA_INIT

      若该值不以@开头,会将其作为一段lua代码进行执行;若以@开头,则将其作为lua文件路径载入并执行

lua.exe -e “myPrint=print” e:LuaTest.lua 100 200

e:LuaTest.lua中的内容如下:

myPrint("Hello")

-- 打印所有传入的命令行参数
for i, v in pairs(arg) do
    myPrint(i, v)
end

输出结果为:

在运行以前,Lua使用所有参数构造arg表。脚本名e:LuaTest.lua索引为0,脚本的参数从1开始增加,脚本前面的参数从-1开始减少 

lua.exe -e “myPrint=print” e:LuaTest2.lua 1 “hello” true

e:LuaTest2.lua中的内容如下:

local a, b, c, d = ...
myPrint(a) -- 1
myPrint(b) -- hello
myPrint(c) -- true
myPrint(d) -- nil

lua.exe -i e:LuaTest3.lua  // 执行e:LuaTest3.lua脚本后,进入交互模式

lua.exe -lmisc.Test4    // 搜索misc.Test4模块,找到后加载并执行模块

lua.exe -e “print(package.path);print(package.cpath)” -l misc.Test4   // 打印出lua模块和c模块的搜索路径,按照这些路径来搜索misc.Test4模块,找到后加载并执行模块

E:Lualua?.lua;E:Lualua?init.lua;E:Lua?.lua;E:Lua?init.lua;E:Lua..sharelua5.3?.lua;E:Lua..sharelua5.3?init.lua;.?.lua;.?init.lua  // 将?替换为miscTest4来搜索lua模块
E:Lua?.dll;E:Lua..liblua5.3?.dll;E:Lualoadall.dll;.?.dll;E:Lua?53.dll;.?53.dll  // 将?替换为miscTest4来搜索c模块

注1:对于5.3版本的Lua,package.path会被设置成环境变量LUA_PATH_5_3的值,若其没定义,则会尝试另外一个环境变量LUA_PATH;若都没定义,则使用编译时定义的默认路径(如上)

注2:对于5.3版本的Lua,package.cpath会被设置成环境变量LUA_CPATH_5_3的值,若其没定义,则会尝试另外一个环境变量LUA_CPATH;若都没定义,则使用编译时定义的默认路径(如上)

注3:在使用环境变量时,可以添加;;来带上默认路径;如:将LUA_PATH定义为c:public;;  package.path则会变成c:public和默认路径(如上)的集合

注4:若命令行带上-E参数,则会在阻止使用环境变量,强制使用默认路径(如上)

Lua C#解释器

Lua Interpreter使用C#实现的解释器,它允许使用C#模块,并能在lua代码中调用这些C#模块中的函数

Lua JIT

LuaJIT是(wiki)一款支持JIT的Lua代码解释器,使用C语言编写,已开源(git);当前发布的稳定版本为2.0.5,最新的版本为2.1.0-beta3,只兼容Lua的5.1版本

编译技术大约分为两种,一种AOT,将源代码、中间码等提前静态地编译成本地机器码,目标用户直接用本地机器码的程序来运行
另一种是JIT(Just In Time,即时编译),一个JIT引擎要想快,它会通过搜集runtime信息,识别出程序的热点(2/8原则),会将这部分代码编译成本地机器码并缓存起来,以便下一次直接运行;
而对于只执行一次或少量次数的代码,JIT编译带来的执行速度的提升也未必能抵消掉其编译带来的时间开销,这部分代码JIT引擎会仍然选择解释的方式执行

从官网上下载源码解压后,在Visual Studio 2008 Command Prompt命令行中,切换当前路径到<LuaJIT>src,然后执行msvcbuild.bat

在src目录中,会得到生成出luajit.exe及依赖文件

要编译得到64位的luajit,则需要在Visual Studio 2008  x64 Win64 Command Prompt命令行中编译

如果想调试运行luajit.exe,可按照如下步骤来

① 在msvcbuild.bat脚本搜索/O2,将/O2改为/Od
② 执行msvcbuild.bat debug来生成luajit.exe
③ 用visual studio建立一个命令行工程,如:luajitcmd
④ 把<LuaJIT>src下所有.h和.c代码加入工程
⑤ 把工程的调试路径设置为
  命令:$(ProjectDir)….srcluajit.exe
  工作目录:$(ProjectDir)….src
⑥ 此时就可以正常按f5下断点调试了

luajit的命令行参数用法与lua.exe/wlua.exe是一致的,只是在其基础上增加了几个命令行参数(详见:这里),可通过luajit.exe –help查看详细用法

luajit.exe -b Hello.lua Hello.luajit  // 将Hello.lua代码编译成luajit字节码(缺省是开启O3最高优化)

luajit.exe -O0 Hello.lua // 关闭优化,执行Hello.lua代码

luajit.exe -joff Hello.lua // 关闭jit,仅仅使用解释器执行Hello.lua代码

关于luajit字节码的详细格式详见:【技术分享】Lua程序逆向之Luajit文件格式

更多请阅读:

Lua程序逆向之Luajit文件格式 

LuaJIT反编译总结 

lua反编译工具

工具名称 下载地址 说明
Unluac

https://github.com/HansWessels/unluac

https://sourceforge.net/projects/unluac/

java语言实现,lua反编译器开源项目,可将lua字节码反编译为lua代码
Luadec

https://github.com/viruscamp/luadec

http://luadec.luaforge.net/

c语言实现,结合lua引擎源码写的开源lua反编译器,解析整个lua字节码文件并尽可能的还原为源码
Chunkspy

https://github.com/viruscamp/luadec/tree/master/ChunkSpy

http://chunkspy.luaforge.net/

lua语言实现,将lua字节码翻译成lua汇编

该工具还包括了一个交互式的命令,可以将输入的lua脚本转换成lua字节码汇编,这对学习lua字节码非常有帮助

Luadec工具中集成了Chunkspy

luajit-decomp https://github.com/bobsayshilol/luajit-decomp au3语言实现,先通过luajit原生的exe文件将luajit字节码文件转换成汇编,然后使用该工具将luajit汇编转换成lua代码
ljd https://github.com/NightNord/ljd python语言实现,一款luajit反编译工具

lua性能分析工具

工具名称 下载地址 说明
pLua https://github.com/esrrhs/pLua lua函数热点分析
lua-snapshot

https://github.com/cloudwu/lua-snapshot

https://blog.codingnow.com/2012/12/lua_snapshot.html

lua内存泄漏
lua_memleak https://github.com/radiotail/lua_memleak lua内存泄漏

游戏引擎lua插件

插件名称 支持引擎 下载地址 说明
xlua unity https://github.com/Tencent/xLua G6
unlua ue4 https://github.com/Tencent/UnLua G6
slua unity https://github.com/pangweiwei/slua 潘多拉(Pandora) 
sluaunreal ue4 https://github.com/Tencent/sluaunreal 潘多拉(Pandora) 
ulua unity https://github.com/jarjin/uLua  
tolua unity https://github.com/topameng/tolua  
unreal.lua ue4 https://github.com/asqbtcupid/unreal.lua tianle

常用库的lua版本

插件名称 下载地址 说明

pb的lua化方案1

protoc-gen-lua

https://github.com/memoryoff/protoc-gen-lua-bin-fix

https://github.com/u0u0/protoc-gen-lua-bin

https://github.com/sean-lin/protoc-gen-lua

需将proto生成lua代码

protoc-gen-lua很久没维护了

protoc-gen-lua-bin适配了lua53版本,并对其做了一些修正

protoc-gen-lua-bin-fix对protoc-gen-lua-bin做了一点修正

支持int64类型补丁:int64 encoder _VarintSize error!

pb的lua化方案2

pbc

https://github.com/cloudwu/pbc

不需要将proto生成lua代码

提供c函数来序列化和反序列化pb字节流

pb的lua化方案3

lua-protobuf

https://github.com/starwing/lua-protobuf

 

luasocket

http://w3.impa.br/~diego/software/luasocket/

https://github.com/diegonehab/luasocket

LuaSocket 是 Lua 的网络模块,提供了对 TCP、UDP、DNS、HTTP 等多种网络协议的访问操作,

包括了两部分:①使用 C 编写的针对 TCP 和 UDP 传输层的访问;②用 Lua 编写,负责应用功能的网络接口处理。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注