Unity toLua載入lua的流程

2021-09-10 01:48:14 字數 4797 閱讀 3505

unity中我們要載入lua檔案呼叫的函式是:luastate類中的dofile("***").我們可以看到流程是:

luastate:dofile()->luastate:loadfilebuffer()->luafileutils:readfile()->findfile()

public void dofile(string filename)

byte loadfilebuffer(string filename)

#endif

byte buffer = luafileutils.instance.readfile(filename);

if (buffer == null)

: no such file or directory", filename);

error += luafileutils.instance.findfileerror(filename);

throw new luaexception(error);

}return buffer;

}

public virtual byte readfile(string filename)

return str;

}else

}

public string findfile(string filename)

if (path.ispathrooted(filename))

return filename;

}if (filename.endswith(".lua"))

string fullpath = null;

for (int i = 0; i < searchpaths.count; i++)

}return null;

}

最後會在searchpaths的路徑中進行搜尋,是否存在指定的lua檔案,來進行載入與否。那這個searchpaths變數在**初始化呢?

第一處是addsearchpath:

我們獲取lua中的package.path來初始化我們的搜尋路徑。

public void initpackagepath()

}luapushstring("");

luasetfield(-3, "path");

luapop(2);

}

第二處是luastate類中的addsearchpath:

initluapath是在luastate建構函式中呼叫的。

void initluapath()

, configer it in luaconst.cs", luaconst.luadir);

throw new luaexception(msg);

}if (!directory.exists(luaconst.toluadir))

, configer it in luaconst.cs", luaconst.toluadir);

throw new luaexception(msg);

}addsearchpath(luaconst.toluadir);

addsearchpath(luaconst.luadir);

#endif

if (luafileutils.instance.gettype() == typeof(luafileutils))

}}

lua中我們是使用require來進行載入其他lua檔案的,首先require的偽**實現如下:

function require(name)

if not package.loaded[name] then

local loader = findloader(name)

if loader == nil then

error("unable to load module" .. name)

endpackage.loaded[name] = true

local res = loader(name)

if res ~= nil then

package.loaded[name] = res

endend

return package.loaded[name]

end

lua原始碼(在loadlib.c中):

1.首先是初始化require搜尋路徑流程

static const lual_reg pk_funcs = ,

,#if defined(lua_compat_module)

,#endif

/* placeholders */

, ,

, ,

, };static const lual_reg ll_funcs = ,

#endif

, };static void createsearcherstable (lua_state *l) ;

int i;

/* create 'searchers' table */

lua_createtable(l, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);

/* fill it with predefined searchers */

for (i=0; searchers[i] != null; i++)

#if defined(lua_compat_loaders)

lua_pushvalue(l, -1); /* make a copy of 'searchers' table */

lua_setfield(l, -3, "loaders"); /* put it in field 'loaders' */

#endif

lua_setfield(l, -2, "searchers"); /* put it in field 'searchers' */}/*

** create table clibs to keep track of loaded c libraries,

** setting a finalizer to close all libraries when closing state.

*/static void createclibstable (lua_state *l)

luamod_api int luaopen_package (lua_state *l)

2.require的原始碼

static int ll_require (lua_state *l) 

return 1;

}static void findloader (lua_state *l, const char *name)

lua_pushstring(l, name);

lua_call(l, 1, 2); /* call it */

if (lua_isfunction(l, -2)) /* did it find a loader? */

return; /* module loader found */

else if (lua_isstring(l, -2))

else

lua_pop(l, 2); /* remove both returns */

}}

根據原始碼知道,將所有的loader:

1.searcher_preload 

搜尋:package.preload 表中是否有指定lua

2.searcher_lua 

搜尋:path 路徑中是否有指定lua

3.searcher_c 

搜尋路徑:cpath路徑中是否有指定lua

4.searcher_croot

搜尋路徑:cpath路徑中是否有指定lua

都加入到了searchers表中,然後require(ll_requre)呼叫的時候,會先判斷這個lua是否載入過,如果沒有載入過那麼就會呼叫

findloader,這個函式會遍歷searchers表,依次在上面的4個函式中去找尋是否有對應的lua檔案。

根據2我們知道require是遍歷所有loader函式來所有lua檔案,於是tolua中在searchers中加入了loader函式來進行搜尋我們的lua檔案,原始碼如下:

luastate建構函式->tolua.openlibs(l)->addlualoader

static void addlualoader(intptr l)

luadll.lua_rawseti(l, -2, 2);

luadll.lua_pop(l, 2);

}[monopinvokecallbackattribute(typeof(luacsfunction))]

static int loader(intptr l)

if (luaconst.openluadebugger)

if (luadll.lual_loadbuffer(l, buffer, buffer.length, "@"+ filename) != 0)

return 1;

}catch (exception e)

}

可以看到這個loader函式最後會呼叫luafileutils.instance.readfile(filename);來找尋要載入的檔案,於是根據1中的介紹,我們知道也就是要在searchpaths中根據路徑來找對應的lua檔案。

lua模組載入

module mod name,package.seeall 函式 通過package.seeall選項可令舊全域性環境可見。require mod name 載入指定的模組。先檢測package.loaded表中是否存在modname,存在則直接返回當中的值,沒有則通重載入器載入modname。p...

Lua動態載入模組

function reload modulename package.loaded modulename nil require modulename end 使用以上 即可重新載入乙個檔案。這樣修改完lua 後,可以不用重啟程式立刻生效。模組a a function a.test1 print 1...

lua載入csv檔案

文章 author my name date 2013 12 16 18 52 11 csv解析 去掉字串左空白 local function trim left s return string.gsub s,s end 去掉字串右空白 local function trim right s ret...