1.lua文件的源码二进制文件如何转换成源代码
2.Lua5.4 源码剖析——杂谈 之 如何调试Lua源码
3.LuaJIT源码分析(一)搭建调试环境
4.lua 与 c++或者c 交互的底层原理谁能解释一下?最最底层的,为什么它们调用C或者C++的源码函数?
5.Unlua源码解析(一) 通过 UE 命名空间访问C++类型
lua文件的二进制文件如何转换成源代码
转换方法有使用luac命令、使用lua2c工具、源码使用反编译工具等。源码
1、源码使用luac命令:luac是源码网站源码psdLua编译器,能将Lua程序编译成二进制文件,源码这些二进制文件可以被加载和执行。源码
2、源码使用lua2c工具:lua2c是源码一个工具,可以将Lua源代码转换为C源代码。源码这个工具是源码用Lua编写的,无需额外的源码构建、安装。源码
3、源码使用反编译工具:有些工具可以将Lua字节码反编译成Lua源代码,包括LuaDec、unluac和Ljd等。
Lua5.4 源码剖析——杂谈 之 如何调试Lua源码
我们有时候写了一段Lua代码,希望能通过断点调试的方式看一下我们的代码在执行过程中Lua虚拟机的状态与运行流程。本篇教程我将教大家Windows与Mac环境下如何配置Lua源码调试环境。linux内核启动源码
Lua调试环境需要有Lua源码,我们从官网下载源码:
Windows下Lua源码调试环境搭建
1)下载Visual Studio,可自行在官网下载最新版本即可:
2)打开VIsual Studio,创建一个新的C++控制台工程,我这里以Visual Studio 版本进行举例:
项目可任意命名,本例中我们命名为TestLua:
3)工程中添加Lua源码文件:
3.1)拷贝源代码文件到项目的文件夹,Makefile文件可以不拷贝:
3.2)把上面这些文件导入工程:
"
.h
头文件导入:导入所有".h"后缀文件到头文件文件夹中(右键头文件->添加->现有项):
"
.c
源文件导入:导入所有".c"后缀文件到源文件的文件夹(右键源文件->添加->现有项):
4)生成exe可执行文件:
文件都导入完成了,这时候如果按"生成"或者"F5",会有如下的报错:
这是因为除了我们创建项目工程的时候自带源文件中的一个main函数以外,Lua源码中也定义了两个Main函数。他们分别对应的是luac编译工具的启动函数和lua运行工具的启动函数。要想编译通过,我们只需要根据自己要调试目的,从3个main里面把用不到的2个main删掉或者重命名即可。
本例中,我打算在自己的main里面实现通过dofile函数执行一个Lua文件的功能,所以我不需要启动lua和luac指令控制台,所以我把他们的main函数改名:
luac.c:把main函数改名为luac_main函数:
lua.c:把main函数改为lua_main:
上述源码中多余的2个main函数都改名了,这时候已经能编译通过并生成出exe可执行文件了。
接下来我们可以开始编写自己的分销erp系统源码main函数逻辑了,打开TestLua.cpp,输入以下内容,作用是运行一个在项目目录下名字为"testlua.lua"的lua文件:
5)testlua.lua文件创建与编写:
上述代码在运行时会执行testlua.lua文件,接下来我们就需要在工程目录下创建这个将要被执行的testlua.lua文件:
打开testlua.lua文件,添加任意lua代码,这里我们简单调用print打印一句信息:
6)在Visual Studio中按“F5”开启调试,可以看到控制台被成功运行,我们的lua文件也被成功执行,打印出了信息:
7)断点调试指令OpCode:
学习过我的《Lua源码剖析 之 虚拟机》系列教程的同学应该知道Lua的指令就是各种OpCode的执行,我们可以在《lvm.c》的下面这个地方加断点再按F5重新启动程序,程序在每执行一条OpCode指令就会在这处代码断点下来,这时候我们就能看到下一条要执行的OpCode是哪一条了:
在本例中的print函数最终会执行到OP_CALL这个调用分支:
Windows环境下搭建Lua源码调试环境的教程到此结束。
Mac下Lua源码调试环境搭建
因为大部分流程与上面Windows一样,所以我下面会省略一些重复步骤。
1)下载XCode,可自行在AppStore进行下载。
2)打开XCode,创建一个新的C++控制台工程,本例中命名为TestLua:
3)工程中添加Lua源码文件:
3.1)拷贝源代码文件到项目的文件夹,Makefile文件可以不拷贝:
3.2)把拷贝后的新闻发布网站源码文件导入工程:
不需要区分".h"和".cpp",全选导进来就好了:
4)与Windows流程同样,把源码自带的2个main函数改名:
luac.c:把main函数改名为luac_main函数:
lua.c:把main函数改为lua_main:
把源码中多余的2个main函数都改名了,接下来同样,开始编写我们的main.cpp,打开该文件并添加代码如下代码。为了在mac下文件读取代码更简洁,在下面的Lua文件我暂时先使用文件的绝对路径,暂时把testlua.lua文件放在我的mac的桌面上进行读取:
5)在mac的桌面上创建testlua.lua文件,添加任意lua代码:
6)同理可正常运行或者加断点进行调试,这里不再赘述:
总结
本文我们学习了如何在Windows与Mac下搭建Lua源码调试环境。另外,我们上述使用的例子是通过dofile运行一个lua文件,同学们也可以试试保留lua.c里面的main函数,删掉另外两个,此时按开始调试可启动lua的即时解析控制台,在控制台里面可自行输入任意Lua代码,并可断点查看即时运行状态或最终结果,感兴趣的同学可以自行试试。
不过,尽管能调试Lua源码,python源码剖析 高清但如果之前没有学习过我的那些Lua源码剖析教程,可能很多地方会看不懂,所以这里建议有空的同学还是可以先去学习一下的。
谢谢阅读。
LuaJIT源码分析(一)搭建调试环境
LuaJIT,这个以高效著称的lua即时编译器(JIT),因其源码资料稀缺,促使我们不得不自建环境进行深入学习。分析源码的第一步,就是搭建一个可用于调试的环境,但即使是这个初始步骤,能找到的指导也相当有限,反映出LuaJIT的编译过程复杂性。
首先,从官方git仓库开始,通过命令`git clone https://luajit.org/git/luajit.git`获取源代码。GitHub上也有相应的镜像地址。对于调试,LuaJIT提供msvcbuild.bat脚本,位于src目录下,它将编译过程分为三个阶段:构建minilua,用于平台判断和执行lua脚本;buildvm生成库函数映射;以及lua库的编译和最终LuaJIT的生成。该脚本需在Visual Studio Command Prompt环境中以管理员权限运行,且有四个可选编译参数。
在调试时,我们无需这些选项,但需要保留中间代码。因此,需要在脚本中注释掉清理代码的部分。在Visual Studio 的位命令提示符中,切换到src目录并运行`msvcbuild.bat`。编译过程快速,成功时会看到日志信息。在src目录下,luajit.exe即为lua虚拟机。
接着,在src目录的同级目录创建一个VS工程,将源文件和头文件添加进来。初次尝试调试可能会遇到关于strerror函数安全性的警告,这可以通过在工程属性中添加_CRT_SECURE_NO_WARNINGS宏来解决。然而,链接阶段可能会出现重复定义的错误,这与ljamalg.c文件的编译选项有关。amalg选项用于生成单个大文件,以优化代码,但我们通常不启用它。
排除ljamalg.c后,再次尝试调试,可能还需要手动添加buildvm阶段生成的目标文件。当LuaJIT启动并设置好断点后,就可以开始调试源码了。至此,你已经成功搭建了一个LuaJIT的调试环境,为深入理解其工作原理铺平了道路。
lua 与 c++或者c 交互的底层原理谁能解释一下?最最底层的,为什么它们调用C或者C++的函数?
因为 lua 解释器就是用 C 语言开发的,而目前 C 语言在协议上与 C++ 是相同的(或者说使用同一套C协议,虽然C++由C衍生,但对于编译器而言反而更像是从C++删减成C,所以C与C++兼容)
Unlua源码解析(一) 通过 UE 命名空间访问C++类型
通过UE4的命名空间访问C++类型的机制,让我们从一个具体的例子出发,即UE4.UKismetSystemLibrary.PrintString(“hello”),来深入解析这一过程。在Unlua提供的例子中,HelloWorld的实现展现了Lua与C++的交互方式。要理解为什么Lua的代码能最终调用C++的方法,并且成功执行,我们需要从底层逻辑出发,解析这一过程中的关键步骤。
首先,我们从Unlua.lua中的声明开始,UE4实际上被表示为全局表_G,其元表为global_mt,Index元方法为global_index。当我们在Lua代码中尝试访问UE4的成员,如UKismetSystemLibrary,实际上是在查找全局表_G中的“UKismetSystemLibrary”。为了实现这一查找,我们引入了元方法,即global_index方法,其在Lua代码中扮演了关键角色。
在访问过程中,当Lua尝试获取表中不存在的“UKismetSystemLibrary”时,会触发元方法global_index。这个过程实际上涉及到一系列的函数调用,包括RegisterClass等。注册类的逻辑在于,将C函数注册为Lua端可以通过全局名称访问的函数。在这一过程中,UE4.UKismetSystemLibrary最终会成为一个Lua端的表,其元表指向自身,并且通过特定的元方法(如Class_Index)来处理访问与调用。
在UE4.UKismetSystemLibrary.PrintString(“Hello”)的调用中,我们可以看到一系列的执行逻辑。首先,通过一系列函数调用,UE4.UKismetSystemLibrary表中实现了PrintString方法的描述信息与调用机制。这个过程涉及到类的注册、属性与方法的描述、以及在Lua端的表中存储这些描述信息。
最终,当执行PrintString方法时,Lua端的调用实际转化为C++端的函数调用。这一过程涉及到参数的转换、方法的调用机制(如PreCall、ProcessEvent、PostCall等),以及最终的返回值转换与处理。这一系列的步骤确保了Lua端的代码能够与C++端的方法进行交互,实现功能的调用与执行。
通过这一解析,我们可以清晰地看到,UE4与Unlua的结合是如何通过元方法、表操作以及函数注册机制,实现了Lua与C++之间的高效通信与调用,使得跨语言编程成为可能。这一机制不仅展示了语言间的交互灵活性,也体现了底层设计在实现复杂功能中的重要性。