2014-01-21 40 views
2

我有一個Lua模塊,它返回一個導出表(即不使用棄用的模塊指令)。此外,我有一個腳本,希望通過「require」函數加載該模塊。 現在,我從C代碼加載這兩個文件到Lua狀態是這樣的:如何在Lua中要求已經加載的模塊

luaL_loadstring(lua, someScript); 
lua_pcall(lua, 0, LUA_MULTRET, 0); 
luaL_loadstring(lua, someModule); 
lua_pcall(lua, 0, LUA_MULTRET, 0); 

的需要調用失敗,因爲它看起來的文件,而不是代碼,它已經加載。在這種情況下,是否有可能需要某些來自someScript的模塊?

+0

我的問題,並要求澄清不適合在這樣就把一個問題中留言,我會根據你的澄清擴展這個問題的答案(這BTW你應該提出你的問題,而不是註釋) – Schollii

回答

1

documentation for require包含您需要使這項工作的所有信息。具體來說,它告訴你require函數用來查找被請求的代碼的方法。更具體地說,關於package.loaded的第一句話是您可能想要關注的內容。從上面的鏈接

文檔:

加載給定的模塊。該函數首先查看package.loaded表來確定modname是否已經加載。如果是,則需要返回存儲在package.loaded [modname]處的值。否則,它會嘗試爲模塊查找加載程序。

要查找加載器,require需要由package.loaders數組指導。通過改變這個數組,我們可以改變需求查找模塊的方式。以下說明基於package.loaders的默認配置。

首先需要查詢package.preload [modname]。如果它有一個值,這個值(這應該是一個函數)是加載器。否則,需要使用存儲在package.path中的路徑搜索Lua加載程序。如果這也失敗了,它將使用存儲在package.cpath中的路徑搜索C加載器。如果這也失敗了,它會嘗試一個all-in-one加載器(請參閱package.loaders)。

一旦找到加載器,require會用一個參數modname調用加載器。如果加載器返回任何值,則需要將返回值分配給package.loaded [modname]。如果加載器沒有返回值並且沒有爲package.loaded [modname]賦值,那麼require會爲此條目賦值爲true。在任何情況下,require都會返回package.loaded的最終值[modname]。

如果在加載或運行模塊時出現任何錯誤,或者找不到模塊的加載器,則需要發出錯誤信號。

+0

嗯,模塊中的最後一條語句返回一個導出表。據我所知,需要一個文件以某種方式調用該返回語句並將結果設置爲package.loaded。我不明白的是,如何在文件已經加載時訪問導出表? –

+0

你的模塊返回一個表格。當你調用luaL_loadstring時,它會在堆棧中放置一個可調用的塊/函數(該函數代表你的文件)。當你使用'lua_pcall'函數時,你在你的文件中運行代碼並返回文件返回的內容。在這種情況下,似乎是一個表。這是您需要返回的表格。 –

0

爲了清楚起見,我們命名爲:模塊A返回一個導出表;腳本B是一個需要模塊A的字符串,我假設B不返回任何內容。同時要做到以下幾點:

load script B (via luaL_loadstring): puts chunk on stack 
run chunk for script B (via lua_pcall): puts whatever B returns on stack 
load module A (via luaL_loadstring): puts chunk on stack 
run module A (via lua_pcall): puts whatever A returns on stack 

首先,模塊A是那麼想必你已經加載的內容轉換成字符串的文件。

你說你的問題是需要在腳本B中調用失敗。可能有幾個原因,比如B需要'moduleA',但在LUA_PATH文件夾中找不到moduleA.lua。

所以:

  • 打印,需要一個,所以我們可以看到代碼
  • 驗證LUA_PATH是這樣的moduleA B的一部分。可以發現lua

一旦上述內容被確認無誤,我們可以看看你的C API調用,但我懷疑這些問題。

0

如果someModule使用require"modname"那就試試這個代碼:

lua_getglobal(lua, "package"); 
lua_getfield(lua, -1, "loaded"); 
luaL_loadstring(lua, someScript); 
lua_pcall(lua, 0, 1, 0); 
lua_setfield(lua, -2, modname); 
luaL_loadstring(lua, someModule); 
lua_pcall(lua, 0, LUA_MULTRET, 0);