unity
- Miku-LuaProfiler
unreadl
- ELuaProfiler
lua_sethook
lua_sethook
函数用于给指定的 lua_State 设置钩子函数。它的函数原型为:
lua_Hook lua_sethook(lua_State *L, lua_Hook func, int mask, int count);
函数的参数含义如下:
-
L
:要设置钩子函数的 lua_State。 -
func
:钩子函数的实践函数,类型为lua_Hook
(typedef 定义的函数指针类型)。 -
mask
:一个掩码,指定了要运用哪些类型的钩子。它由下面几个常量按位或组合而成:-
LUA_MASKCALL
:当 Lua 调用函数时产生。 -
LUA_MASKRET
:当函数回来时产生。 -
LUA_MASLINE
:当履行一行指令时产生。 -
LUA_MASKCOUNT
:当 Lua 履行指定数量的指令时产生。 -
LUA_MASKALL
:包括一切钩子类型。
-
-
count
:钩子函数被调用的频率。关于LUA_MASKCOUNT
钩子类型有特殊含义,指定了多少条指令后触发一次钩子函数。关于其他钩子类型,该参数可所以恣意整数。
在上述代码中,lua_sethook(L, myhook, LUA_MASKCOUNT, 1)
指定了运用 LUA_MASKCOUNT
类型的钩子,并将钩子函数 myhook
注册到 L
中,设定每履行一条 Lua 指令时,都会调用 myhook
一次。因此,当履行一行指令后,myhook 函数就会被调用一次,完成对 Lua 程序指令计数的操作。
需求注意的是,Lua 中的钩子机制需求细心设计,由于它可能会影响程序功用,乱用钩子功用可能会导致程序呈现难以调试或了解的问题。主张在运用钩子之前对钩子的运作原理进行深入研究,并充沛测验和验证代码的正确性。
lua_getinfo
lua_getinfo
函数用于获取指定调用层次上的函数信息。这个函数能够在钩子函数中运用,也能够在 Lua 中调用。以下是该函数的详细阐明:
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
该函数承受三个参数:
-
L
:Lua 状态机。 -
what
:一个字符串常量,表明要获取的信息。它由一系列控制字符组成,每个字符表明要获取的某一类信息。以下是可用的控制字符列表:-
'n'
:函数名。 -
'S'
:Lua 源码文件名。 -
'l'
:代码在源码文件中地点的行号。 -
'f'
:函数地址。 -
'L'
:当时层次的栈信息。 -
'u'
:协程信息。 -
't'
:关于主函数或尾调用的信息。 -
'r'
:关于正在运行的函数的信息。
其间,
'n'
,'S'
和'l'
是最常用的控制字符。同时指定多个控制字符的方式是将它们组合在一起,例如"Sln"
表明获取函数名、Lua 源码文件名和代码行号信息。 -
-
ar
:一个lua_Debug
结构体指针,用于存储获取到的信息。
该函数回来一个整数值表明操作是否成功。假如成功,回来 1;不然回来 0。假如传递了无效参数,例如 what
包含了未定义的控制字符,则回来 0。
在调用 lua_getinfo
函数后,假如获取到了所需信息,则这些信息会被存储在 lua_Debug
结构体中。例如:
lua_Debug ar;
lua_getinfo(L, "nSl", &ar);
std::cout << "function name: " << ar.name << std::endl; // 函数名
std::cout << "source file name: " << ar.source << std::endl; // 源码文件名
std::cout << "current line number: " << ar.currentline << std::endl; // 当时行号
在以上示例中,我们经过将 "nSl"
作为 what
参数传递给 lua_getinfo
函数,来获取函数名、源码文件名和代码行号信息。注意,在获取某些信息(例如代码行号)时,你需求在 Lua 中敞开调试模式(经过 lua_sethook
函数完成)。此外,lua_getinfo
函数的效率较低,假如需求高效功用的话,主张仅获取必要的信息,并尽量减少调用次数。
注意:
运用 lua_getinfo
函数获取 Lua 函数信息时,该函数会将相关信息压入仓库中,这些信息以一个 Lua 表(table)的方式保存在仓库顶部。
验证代码
int size1 = lua_gettop(L); // 0
lua_getinfo(L, "Slnf", ar);
int size2 = lua_gettop(L); // 1
完成原理
大部分 Lua 功用剖析东西一般运用了以下几个接口:
-
lua_getinfo
– 获取函数的信息。能够用于获取当时正在履行的函数的调用信息,包括当时履行的行号、文件名等。 -
lua_sethook
– 设置钩子函数。经过设置钩子函数能够在程序履行过程中插入额外的操作,例如收集履行时间、记录调用深度等。其间的mask
参数能够根据需求挑选不同的钩子类型,例如调用、回来和行数。 -
lua_toclose
– 获取当时函数地点的履行环境。当调用栈的某一层被弹出时,会调用该函数来获得该层的上下文信息。
经过这些接口,功用剖析东西能够盯梢函数调用、捕获函数履行时间并输出相关信息,从而帮助开发人员发现程序瓶颈并优化功用。
除此之外,还有一些其他的 Lua 接口能够用于功用剖析,例如 lua_pcall
、lua_next
、lua_pushstring
等。开发人员也能够根据自己的需求以及对 Lua 内部机制的深入了解,设计更加专业、高效的功用剖析东西。