2014-01-21 2 views
2

У меня есть модуль Lua, который возвращает таблицу экспорта (т. Е. Не использует директиву устаревших модулей). Кроме того, у меня есть сценарий, который хочет загрузить этот модуль с помощью функции «require». Теперь я загрузить оба файла в состоянии Lua из кода C, как это:Как запросить уже загруженные модули в Lua

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

Требовать вызов терпит неудачу, потому что он ищет файл, а не код, который уже загружен. Возможно ли в какой-то мере потребовать someModule от someScript в этой ситуации?

+0

Мои вопросы и просьбы о разъяснениях не вписывались в комментарии так поставить в вопросе, я продлит этот ответ основан на ваших разъяснениях (которые BTW вы должны задать свой вопрос, а не комментарии) – Schollii

ответ

1

documentation for require содержит всю информацию, необходимую для выполнения этой работы. В частности, он сообщает вам, какая методология использует функция require, чтобы найти запрашиваемый код. Более конкретно, первое предложение о package.loaded - это то, на что вы, вероятно, захотите обратить внимание.

Документация из выше ссылке:

загружает данный модуль. Функция начинается с поиска в таблице package.loaded, чтобы определить, загружено ли modname. Если это так, тогда требуется вернуть значение, сохраненное в package.loaded [modname]. В противном случае он пытается найти загрузчик для модуля.

Чтобы найти загрузчик, требуется руководствоваться массивом package.loaders. Изменяя этот массив, мы можем изменить, как требуется искать модуль. Следующее объяснение основано на настройке по умолчанию для package.loaders.

Сначала требуются запросы package.preload [modname]. Если оно имеет значение, это значение (которое должно быть функцией) является загрузчиком. В противном случае требуется выполнить поиск загрузчика Lua, используя путь, сохраненный в package.path. Если это также не удается, он ищет загрузчик C, используя путь, сохраненный в package.cpath. Если это также терпит неудачу, он пытается загрузчик «все-в-одном» (см. Package.loaders).

Как только загрузчик найден, требуется вызвать загрузчика с одним аргументом, именем модели. Если загрузчик возвращает любое значение, требуется присвоить возвращаемое значение package.loaded [имя_модема]. Если загрузчик не возвращает значение и не присвоил значение package.loaded [имя_модема], тогда требуется назначить true для этой записи. В любом случае требуется вернуть окончательное значение package.loaded [modname].

Если есть какая-либо ошибка при загрузке или запуске модуля или если он не может найти загрузчик для модуля, то для получения сигнала требуется ошибка.

+0

Хммм, последнее утверждение в модуле возвращает таблицу экспорта. Насколько я понимаю, требование файла каким-то образом вызывает этот оператор return и устанавливает результат в package.loaded. Я не понимаю, как получить доступ к таблице экспорта, когда файл уже загружен? –

+0

Ваш модуль возвращает таблицу. Когда вы вызываете 'luaL_loadstring', он помещает вызываемый кусок/функцию в стек (функция представляет ваш файл). Когда вы 'lua_pcall', эта функция запускает код в вашем файле и возвращает возвращаемый файл. В этом случае это выглядит как таблица. Это та таблица, в которой вам также потребуется вернуться. –

0

Для наглядности давайте назовем вещи: модуль A возвращает таблицу экспорта; script 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 

Во-первых, модуль А файл так, вероятно, вы загрузили содержимое в строку.

Вы говорите, что ваша проблема связана с требованием, вызванным сценарием B, терпит неудачу. Могло быть несколько причин, таких как B требует «moduleA», но moduleA.lua не найден в папках LUA_PATH.

Итак:

  • печати часть B, которая требует, чтобы мы могли увидеть код
  • убедитесь, что LUA_PATH таково, что ModuleA.lua может быть найден

Как только подтвержденное подтвердится, все в порядке, мы можем посмотреть ваши вызовы API C, но я сомневаюсь, что это проблемы.

0

Если someModulerequire"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); 
Смежные вопросы