我的解决方案是在加载主脚本之前构建全局环境的哈希表。当我需要获取用户定义的全局变量时,我只显示哈希表中不存在的全局变量。通过这种方式,脚本可以全速运行,而无需在运行时跟踪全局变量。
我的解决方案示例(这是我的实现的简短版本):
// The hash table storing global names
std::set<unsigned int> Blacklist;
// Create hash table "Blacklist"
void BlacklistSnapshot(lua_State *L) {
lua_pushglobaltable(L);
lua_pushnil(L);
while (lua_next(L,-2) != 0) { // pop NIL, push name,value
Blacklist.insert(HashName(lua_tostring(L,-2))); // insert to hash table
lua_pop(L,1); // remove value
}
lua_pop(L,1); // Remove global table
}
// Display user defined globals only
void PrintGlobals(lua_State *L) {
lua_pushglobaltable(L);
lua_pushnil(L);
while (lua_next(L,-2) != 0) { // pop NIL, push name,value
// Check if the global is present in our blacklist
if (Blacklist.find(HashName(lua_tostring(L,-2))) == Blacklist.end()) {
// Not present, print it...
PrintFormattedVariable(lua_type(L,-1),lua_tostring(L,-2));
}
lua_pop(L,1); // remove value
}
lua_pop(L,1); // remove global table
}
void RunScript(void) {
// Create new Lua state
L = luaL_newstate();
// Load all Lua libraries
luaL_openlibs(L);
// Create co-routine
CO = lua_newthread(L);
BlacklistSnapshot(CO);
// Load and compile script
AnsiString script(Frame->Script_Edit->Text);
if (luaL_loadbuffer(CO,script.c_str(),script.Length(),"Test") == LUA_OK) {
lua_resume(CO,NULL,0);
} else {
cs_error(CO, "Compiler error: "); // Print compiler error
}
}
该函数HashName
接受一个字符串并将其哈希键作为一个返回,unsigned int
在这里使用您喜欢的任何哈希算法...
当您需要显示全局变量时,请调用PrintGlobals()
(我从hook
例程中执行)