Оценка-заполнитель кода lua

У меня есть приложение, которое использует файлы lua для некоторых из наиболее неясных параметров конфигурации. По сути, он в основном содержит вызовы приложения для создания вещей и изменения свойств; большинство функций C не имеют возвращаемого значения, но некоторые имеют.

Теперь мне нужно прочитать эти же файлы конфигурации в другом приложении и выполнять существенно разные вещи при вызове функций (поэтому я не могу использовать общий код). Кроме того, меня интересует только подмножество возможных функций, и я думаю, что могу по умолчанию игнорировать (и / или возвращать nil) любой другой вызов функции.

Так что мне интересно, какой здесь лучший подход. Как (из приложения C ++) я могу загрузить и выполнить lua-скрипт, чтобы выражения и т. функции?

(Примечание: у меня есть доступ к словарю исходного приложения, которое в основном использует luabind; я мог бы просто использовать те же определения и изменить реализацию, но это слишком хрупко, поскольку в исходное приложение может быть добавлено больше функций позже. I хотелось бы что-то более общее.)


Цель состоит в том, чтобы получить немного кода C, который я могу использовать в качестве общего заполнителя; конечным результатом будет «все, что определено (стандартные библиотечные подпрограммы, функции, определенные в Lua, и функции C, явно зарегистрированные), вызывайте это как обычно; для всего остального вызовите одну конкретную подпрограмму, которая просто ничего не делает, вместо того, чтобы вызывать ошибку». И желательно что-нибудь совместимое с luabind.

Весь процесс инициируется фрагментом кода C, который настраивает среду Lua, загружает набор файлов, вызывает одну функцию и затем разрушает среду. Ничего не будет происходить.


lua
person Miral    schedule 20.10.2009    source источник


Ответы (3)


Установите метаметод __call для nil:

debug.setmetatable(nil, { __call=function () end })

Метаметод _index для _G или других таблиц не работает, потому что имя разрешается до вызова.

(Вам не нужно использовать API отладки или библиотеку, если вы устанавливаете это из C.)

person lhf    schedule 21.10.2009
comment
Я отметил этот вариант (на данный момент), потому что до сих пор он, кажется, работает немного лучше, чем другие варианты, хотя он также требует предварительной регистрации таблиц / подтаблиц, содержащих функции. (Что нормально, но было бы неплохо, если бы с этим тоже можно было справиться автоматически.) - person Miral; 22.10.2009
comment
Я не уверен, что вы имеете в виду, но вы можете добавить __index в таблицу выше: debug.setmetatable (nil, {__call = function () end, __index = function () end}) Это заставит ab вернуть nil, если a равно не определено. - person lhf; 22.10.2009
comment
Приносим извинения за задержку, но какое-то время я работал над другими проектами. Использование __index, похоже, делает то, что я хочу, спасибо! - person Miral; 18.12.2009

Как насчет использования setfenv и metatable? Вы можете заменить глобальную таблицу окружения определенной функции пустой таблицей. А затем установите функцию-заполнитель, чтобы игнорировать C-определенную функцию.

local env = {}  -- empty environment
local metatbl = {}
function metatbl.__index (tbl, key)  -- provides placeholder function
    return function()
        print(key .. " called")
        return(nil)
    end
end

setmetatable(env, metatbl)

function samplefunc()  -- your Lua code goes here
    globalfunction "xyz"   -- calls placeholder function
end

setfenv(samplefunc, env)
samplefunc()

Если вы хотите использовать встроенную функцию, такую ​​как print, вы можете вставить ее в env talbe, например:

local env = {print = print}
person torus    schedule 21.10.2009
comment
Извините, возможно, я неправильно это объяснил. Я хочу, чтобы все стандартные функции библиотеки Lua по-прежнему работали как обычно (хотя при этом было бы полезно игнорировать некоторые из них, такие как функции ввода-вывода файлов). И я не хочу писать больше кода на lua; функции замены заменяют функции C и сами должны быть написаны на C, а код для настройки также должен быть на C. - person Miral; 21.10.2009
comment
@Miral: Ваша проблема со стандартными библиотечными функциями была рассмотрена в конце этого ответа. Кроме того, все, что написано на Lua, также может быть написано на C (хотя это будет сложнее). Кроме того, luaL_dostring () может использоваться для загрузки аналогичного кода Lua изнутри C. - person gwell; 21.10.2009
comment
@gwell: В некотором роде, за исключением того, что требуется, чтобы каждая вещь, над которой я хочу работать, добавлялась индивидуально, что не так уж и хорошо. Я пробовал вариант, в котором для env было установлено значение getfenv (0) вместо {}. Это работало нормально для глобальных функций, но не для вложенных таблиц, и в этом случае давало довольно неясную (для пользователя) ошибку. - person Miral; 22.10.2009

Если у вас есть способ отличить функции C от обычных функций Lua в вашем скрипте, вы можете перебирать все функции, определенные в вашей системе Lua, и для каждой функции C, которая не входит в список функций, которые вам нужны, замените реализация этой функции с простым возвратом к нулю. Это действительно просто, если все c-связывающие функции аккуратно определены вместе в таблице; если они в _G, у вас впереди небольшая работа. Функции, которые вы выполняете, как обычно связываются через luabind.

person David Seiler    schedule 20.10.2009
comment
Некоторые из них являются глобальными, а некоторые находятся в таблицах (а некоторые - в подтаблицах). В этом случае я доволен тем, что не предполагаю ошибок, поэтому в основном все, что уже определено как функция, должно быть функцией lua, а все, что неизвестно, может быть либо функцией C, либо именем таблицы. Я знаю имена таблиц и функций, которые существуют в настоящее время, но я бы хотел не полагаться на эти знания, поскольку исходное приложение является расширяемым. - person Miral; 21.10.2009