- 论坛徽章:
- 11
|
本帖最后由 zylthinking 于 2013-09-12 01:56 编辑
@starwing83
如下代码, 根据输出, 可以得出如结论:
1. luaopen_base(L); 会在栈上压入 _ENV 表
2. 一旦执行
luaL_loadfile(L, "./c.lua");
lua_pcall(L, 0, 0, 0);
完毕后, _ENV['prt'] 是存在的, 也就是 c.lua 中的 prt 函数注册到了 _ENV, 而且 _G 或者 _ENV['_G'] == _ENV, 这个也可以从 c.lua 最后一句,
_G["prt"](_G); 可以正确执行得出。
3. lua_getglobal(L, "prt");
lua_pushvalue(L, 1);
lua_pcall(L, 1, 0, 0);
是可以正确执行的, 似乎 prt 可以从 global 中找到
4. 经实验得知,
lua_pushnumber(L, 2);
lua_gettable(L, LUA_REGISTRYINDEX);
可以拿到 _ENV
问题是, 从 2 可知, _ENV['prt'] 应该也能够拿到 prt, 那么为什么
lua_pushstring(L, "prt"); // 3
lua_pushnumber(L, 2);
lua_gettable(L, LUA_REGISTRYINDEX);
lua_gettable(L, -1);
printf("===========%p\n", lua_topointer(L, -1)); // NULL
却偏偏拿到 null 呢- lua_State* L = lua_newstate(MyAlloc, 0);
- if (L == NULL) {
- return 0;
- }
- luaopen_base(L); // 1
- printf("%s\n", lua_typename(L, lua_type(L, 1)));
- printf("%s\n", lua_typename(L, lua_type(L, -1)));
- printf("%p\n", lua_topointer(L, -1));
- luaopen_table(L); // 2
- luaL_openlibs(L);
- luaL_loadfile(L, "./c.lua");
- lua_pcall(L, 0, 0, 0);
- lua_getglobal(L, "prt");
- lua_pushvalue(L, 1);
- lua_pcall(L, 1, 0, 0);
- lua_pushstring(L, "prt"); // 3
- lua_pushnumber(L, 2);
- lua_gettable(L, LUA_REGISTRYINDEX);
- printf("---------------------%p\n", lua_topointer(L, -1)); // get _ENV
- lua_gettable(L, -1);
- printf("===========%p\n", lua_topointer(L, -1)); // should be _ENV['prt'], but get NULL
- printf("%s\n", lua_typename(L, lua_type(L, -1)));
- printf("%s\n", lua_typename(L, lua_type(L, -2)));
- check(L);
- lua_pushvalue(L, 1);
- lua_pcall(L, 1, 0, 0);
- c.lua
- print(_G);
- print(_ENV);
- function prt(t)
- for key in pairs(t) do
- print(key)
- end
- end
- _G["prt"](_G);
复制代码 输出:
table
table
0x152f5f0 // printf("%p\n", lua_topointer(L, -1));
table:0x152f5f0 // print(_G);
table:0x152f5f0 // print(_ENV);
_ENV 内容:
prt
string
setmetatable
rawlen
tostring
pairs
tonumber
rawget
loadfile
pairsByKeys
loadstring
t
key1
collectgarbage
load
_VERSION
package
print
type
select
rawset
os
pcall
module
_G
lines
key2
next
math
xpcall
bit32
io
table
coroutine
require
assert
dofile
error
ipairs
unpack
debug
rawequa
getmetatable
-----------0x152f5f0 // 可知, 仍然是 _ENV, 此时 stack[-2] == prt, stack[-1] = _ENV
===========(nil)
|
|