Есть ли способ программно определить в C / C ++, сколько параметров ожидает функция Lua? - PullRequest
3 голосов
/ 24 апреля 2009

Есть ли способ определить, сколько параметров принимает функция Lua перед вызовом из кода C / C ++?

Я посмотрел на lua_Debug и lua_getinfo, но они не дают того, что мне нужно.

Может показаться, что я иду против духа Lua, но я действительно хочу пуленепробиваемый интерфейс, который у меня есть между Lua и C ++. Когда функция C ++ вызывается из кода Lua, интерфейс проверяет, что Lua предоставил правильное количество аргументов, и тип каждого аргумента является правильным. Если с аргументами обнаружена проблема, выдается lua_error.

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

Ответы [ 5 ]

5 голосов
/ 24 апреля 2009

То, что вы просите, невозможно в Lua.

Вы можете определить функцию Lua с помощью набора аргументов, например:

function f(a, b, c)
   body
end

Однако Lua не накладывает ограничений на количество аргументов, передаваемых этой функции.

Это действительно:

f(1,2,3,4,5)

Дополнительные параметры игнорируются.

Это также верно:

f(1)

Остальным аргументам присваивается значение «ноль».

Наконец, вы можете определить функцию, которая принимает переменное число аргументов:

function f(a, ...)

В этот момент вы можете передать функции любое количество аргументов.

См. Раздел 2.5.9 Справочного руководства Lua .

Лучшее, что вы можете здесь сделать, - это добавить проверки в ваши функции Lua, чтобы убедиться, что вы получаете ожидаемые аргументы.

4 голосов
/ 11 ноября 2011

Вы можете определить количество параметров, значений повышения и то, принимает ли функция переменное число аргументов в Lua 5.2, используя тип 'u' для заполнения nups, nparams, isvararg полей с помощью get_info () . Эта функция недоступна в Lua 5.1.

2 голосов
/ 30 апреля 2009

Я бы не стал делать это на стороне Lua, если вы не полностью контролируете проверяемый код Lua. Обычно функции Lua игнорируют дополнительные аргументы, просто пропуская их.

Один пример - это когда мы не хотим реализовывать некоторые методы и использовать функцию-заглушку:

function do_nothing() end

full_api = {}
function full_api:callback(a1, a2) print(a1, a2) end

lazy_impl = {}
lazy_impl.callback = do_nothing

Это позволяет сохранить набор текста (и немного производительности), повторно используя доступные функции.

Если вы все еще хотите выполнить проверку аргументов функции, вы должны статически проанализировать код. Одним из инструментов для этого является Metalua .

1 голос
/ 30 апреля 2009

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

С другой стороны, вы можете предоставить систему для разработчиков функций (будь то в чистом Lua или в C), чтобы объявить, сколько параметров ожидают их функции. После создания функции (функция f (a, b, c) end) они просто передадут ее глобальной функции (register (f, 3)). После этого вы сможете извлечь эту информацию из своего кода C ++, и если функция не объявляет свои параметры, то получите запасной вариант к тому, что у вас есть сейчас. С такой системой вы могли бы даже объявить тип, ожидаемый параметрами.

1 голос
/ 25 апреля 2009

Нет, не в пределах стандартного Lua. И, как говорит Аарон Саарела, это несколько выходит за рамки духа Луа, насколько я понимаю. Способ Lua состоит в том, чтобы убедиться, что сама функция рассматривает nil как разумное значение по умолчанию (или преобразует его в разумное значение по умолчанию с чем-то вроде name = name or "Bruce" перед первым использованием), или если нет разумного значения по умолчанию, функция должна либо выдает ошибку или возвращает ошибку (if not name then error"Name required" end является распространенной идиомой для первой, а if not name then return nil, "name required" end является распространенной идиомой для последней). Взяв на себя ответственность Lua за свои собственные проверки аргументов, вы получаете это преимущество независимо от того, вызывается ли функция из Lua или C.

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

Если вы беспокоитесь о пуленепробиваемости, вы можете захотеть контролировать функциональную среду, чтобы проявлять осторожность с тем, какие (если таковые имеются) глобальные переменные доступны стороне Lua, и использовать lua_pcall() вместо lua_call(), чтобы вы ловите любые сгенерированные ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...