使用Lua访问函数体
我在这里回归基础,但在Lua中,您可以这样定义一个表:
myTable = {}
myTable [1] = 12
打印表引用本身会将指针返回给它。要访问其元素,您需要指定索引(即完全像数组一样)
print(myTable ) -- 打印指针
print(myTable[1]) -- 打印12
现在函数是另一回事。你可以这样定义和打印一个函数:
myFunc = function() local x = 14 end -- 定义函数
print(myFunc) -- 打印函数指针
有没有一种方法可以访问定义函数的主体。我正在尝试组合一个小代码可视化器,并希望通过特殊函数/变量“播种”给定函数,以允许可视化器将自身“挂钩”到代码中,我需要能够重新定义函数,无论是从变量还是从字符串。
原文链接 https://stackoverflow.com/questions/504338
请查看调试库中的Lua内省设施。
调试库中的主要内省函数是debug.getinfo函数。它的第一个参数可以是一个函数或堆栈级别。当您为某个函数foo调用debug.getinfo(foo)时,您会得到一个包含有关该函数的一些数据的表。该表可能具有以下字段:
我认为您想要的字段是'func'。
在纯 Lua 中,无法访问给定函数的源代码。源代码在编译成字节码后被丢弃。
顺便提一下,函数可以使用类似 loadstring 的工具在运行时定义。
部分解决方案是可能的 - 这取决于您实际想要实现什么。
您可以从调试库中获取源代码位置 - 如果启用了调试库,并且字节码未剥离调试符号。然后您可以加载实际的源文件并从那里提取代码。
您可以手动使用所需的元数据装饰您感兴趣的函数。请注意,Lua 中的函数是有效的表键,因此您可以创建一个函数到元数据表。您需要将此表变为弱键,以使其不会阻止 GC 回收函数。
如果您需要一个用于分析 Lua 代码的解决方案,请查看 Metalua。
使用调试库是你唯一的选择。使用它,你可以获取函数定义所在的文件名和起始和结束行号以及字符串(如果函数是在使用'loadstring'加载的块中定义的)。请参见文档。
在我目前的工作中,我们已经对Lua进行了补丁,以便为你提供函数开始和结束的列号,因此你可以使用它获取函数源代码。这个补丁不是很难重现,但我不认为我能在这里发布它 :-(
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你可以通过为每个函数创建一个环境(参见setfenv)并使用全局(而不是局部)变量来实现此目的。在函数中创建的变量将在函数执行后出现在环境表中。
env = {} myFunc = function() x = 14 end setfenv(myFunc, env) myFunc() print(myFunc) -- 输出指针 print(env.x) -- 输出14
另外,您还可以使用调试库:
> myFunc = function() local x = 14 ; debug.debug() end > myFunc() > lua_debug> _, x = debug.getlocal(3, 1) > lua_debug> print(x) -- 输出14
您最好使用挂钩函数检索本地变量,而不是显式地进入调试模式(例如添加debug.debug()调用)
在Lua C API中还有一个调试接口。