Require mechanism in Lua
To facilitate code management, Lua code is usually divided into different modules and loaded in through the require function. Now let's take a look at the Lua require processing process.
1. Data and functions related to the require Mechanism
Package. path: stores the search path of the loaded external module (the concept of "module" and "file" in Lua is vague, because the value plays a different role at different times, this path is "template-based path", which contains replaceable symbols "? ", This symbol will be replaced, and Lua will check whether the file exists. If yes, it will call a specific interface. Typical values:
"./?. Lua ;./?. LC;/usr/local /? /Init. Lua"
If you call require ("Hello. World") in Lua code ")
Then Lua will search for the following in sequence:
./Hello/World. Lua => here, "Hello. World" is changed to "Hello/World" and the model is replaced "./?. Lua"
./Hello/World. LC
.....
(This method is similar to Python, except that _ init _. py is not required, and _ init _. py in python is also called)
Package. Path is set when the VM is started. If the environment variable lua_path exists, use this environment variable
And replace ";" in this environment variable with the default value defined in luaconf. H. If this variable does not exist, use it directly.
Default value defined by luaconf. h
Package. cpath: works the same way as packag. path, but it is used to load third-party C libraries. Its initial values can be changed through environment variables.
Lua_cpath to set
Package. loadlib (libname, func): equivalent to manually opening the libname of the c library and exporting the function func to return, loadlib is actually ll_loadlib
2. Process of require:
Require (modelname)
The query order of require (which is the ll_require function in Lua) is as follows:
A. First, find modelname in package. Loaded. If this module already exists, return its value directly.
B. Find modelname in package. preload. If preload exists, use it as the loader and call loader (l)
C. according to package. find the modelname Of The Lua library in the path mode, which is defined by the module function. For the top-level Lua library, the file name is similar to the library name, and you do not need to call the module function explicitly in the Lua file (you can see the processing method in the ll_require function ), that is to say, Lua completes the initialization process of a loader based on the Lua file.
D. according to package. cpath searches for the C library, which complies with some Lua specifications (export has function interfaces with certain characteristics). Lua has loaded the C library dynamically first, search for and call the interface with the corresponding name in the database, for example, luaopen_hello_world.
E. the first ". "For segmentation, the module name is divided into :( main, sub) form, according to package. cpath searches for Main. If it exists, load the library and query the corresponding interface: luaopen_main_sub. For example, first query the hello library and query the luaopen_hello_world interface.
F. After obtaining the Loder, use modname as the unique parameter to call the loader function. Of course, the parameters are passed through the Lua stack, so the loader prototype must comply with Lua specifications: int lua_func (lua_state * l)
Ll_require will give the loader return value to package. loaded [modelname]. If the loader does not return a package at the same time. when loaded [modelname] does not exist, ll_require will set the package. set loaded [modelname] to true. Finally, ll_reuqire returns package. Loaded [modelname] to the caller.
3. module processing process
Module (name, CB1, CB2 ,...)
A. If package. Loaded [name] is a table, use this table as a mod.
B. If the global variable name is a table, use this global variable as a mod.
C. create Table: t = {[name] = package. loaded [name], ["_ name"] = Name, ["_ m"] = T, ["_ package"] = * name * (Delete the last ". XXXX "part )}. if name is a string separated by vertices, the resulting mod looks like this:
Hello. World ==>{ ["hello"] = {["world"] ={ xxxxxxx }}}
D. Call CBS in sequence:
CB1 (MOD), CB2 (MOD ),...
E. Set the environment of the current module to mod, and set package. Loaded [name] = mod
After understanding how Lua processes modules, it is easier to understand the details of writing Lua extensions.
From: http://blog.chinaunix.net/uid-552961-id-2736410.html