首先看一段小小小程序
//test.lua
//test.c
上面的代码就是在test.c中调用test.lua的函数printmsg函数
对于上面的C代码,我想大家都知道几个函数的大概作用:
luaL_newstate():创建一个新的Lua虚拟机
luaL_openlibs() :打开一些必要的库,比如print等
lua_loadfile():手册上写的是"This function uses lua_load
to load the chunk in the filenamedfilename
." 而lua_load就是把编译过的chunk放在stack的顶部。理解chunk很重要,后面会具体讲到
lua_pcall : 执行栈上的函数调用
一开始我一直认为既然luaL_loadfile执行以后,就可以直接使用lua_getglobal获得test.lua中的函数,其实不然。手册中明确提到,lua_load把一个lua文件当作一个chunk编译后放到stack的栈顶,而什么是chunk呢?chunk就是一个可执行语句的组合,可以是一个文件也可以是一个string
“Lua handles a chunk as the body of an anonymous function with a variable number of arguments” 这是Lua对chunk也就是lua文件的处理方式,就是认为是一个可变参数的匿名函数。也就是说,调用后栈上有一个匿名函数,这个函数的body就是文件中所有的内容。
在luaL_loadfile后,调用lua_getop以及lua_type可以知道栈的大小为1,放在栈上的是一个fucntion类型的value。为什么loadfile后我们不能直接获取到printmsg这个函数呢,那是因为刚才提到的,loadfile仅仅视编译lua文件,并不执行这个文件,也就是说只是在栈上形成了一个匿名函数。只有执行这个函数一次,才会使得printmsg可以通过lua_getglobal获取,否则,全局变量是空的。
我在手册上看到这样一句话:Lua在执行函数的时候,函数会实例化,获得的closure也是这个函数的最终值。
其实不管视函数,还是其他类型,如果不执行的话,它们只是被编译,并不能在进程的空间种获取到他们,感觉就像c的库一样,他们的编译文件.so已经存在,但是如果你不调用它,那么库中所有的变量不能被实例化,调用者也就无法访问。
其实pringmsg和x本质是一样的,只是他们类型不同而已。