Я не совсем уверен, что понимаю, что вы просили.Итак, позвольте мне объяснить ваш вопрос.
У вас есть код Lua.В этом коде Lua у вас есть система.В какой-то момент эта система получает одно или несколько событий.Для каждого заданного события он вызывает некоторую функцию или функции, которые были зарегистрированы для вызова при получении данного конкретного события.
Итак, эта система имеет две основные функции:
EventSystem:RegisterEventHandler(EventName, Func);
EventSystem:FireEvent(EventName, ...);
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * '* ”} * * * * * * * Вызывается * Func
, если EventName
, данное FireEvent
, является тем жеFunc
было зарегистрировано.
Теперь вы хотите, чтобы C-код мог регистрировать C-функции как обработчики событий.Настало время поговорить о регистрации функций Си в Lua.
Вызов API C lua_register
на самом деле является макросом.Он создает функцию C в стеке Lua, а затем помещает ее в глобальную таблицу, используя строковый индекс, заданный для lua_register
.Это две отдельные операции;lua_register
- это просто вспомогательная функция, которая делает их одинаковыми.
Вам нужно вызвать RegisterEventHandler
из кода C, передав функцию C в качестве третьего параметра (помните: первый параметр - * 1028).*, потому что я позвонил RegisterEventHandler
с :
вместо .
. Если вы используете глобальную систему событий, а не объектно-ориентированную, у вас есть только два параметра).Это требует двух вещей:
- Вы должны знать, как вызывать функции Lua из кода C.
- Вы должны знать, как передать функцию C в код Lua.
Шаг 1: Все это делается через стек Lua (я предполагаю, вы знаете, как это работает. Если нет, у меня есть довольно существенный ответ, который объясняет почти все, что выВозможно, вы захотите узнать об этом ).
Первое, что вам нужно сделать, это получить функцию, которую вы хотите вызвать, в стек.Для этого вам нужно получить объект системы событий (опять же, если ваша система событий глобальна, просто получите глобальную таблицу) и поместить его в стек.Как вы это сделаете, зависит от того, где хранятся ваши объекты системы событий.Предположительно вы можете получить их через глобальную таблицу.
Как только система событий окажется в стеке, вы просто проиндексируете ее строкой "RegisterEventHandler"
, которая вернет вам нужную нам функцию Lua.
Далее мы помещаем наши параметры в стек, от первого до последнего.Первый параметр - это объект системы событий;это, вероятно, все еще в стеке, поэтому мы можем скопировать его.Второе - это название события, и его легко нажать.Третье - это функция C.Что приводит нас к:
Шаг 2: lua_register
не собирается выполнять работу.Это слишком тяжело;он помещает функцию C в глобальную таблицу.Нам нужно это в стеке.Поэтому мы должны использовать функцию более низкого уровня: lua_pushcclosure
.Или lua_pushcfunction
, если вам не нужны значения вверх.
Эти функции принимают функцию C, оборачивают ее в Lua и помещают в стек Lua.
Теперь, когда 3параметры находятся в стеке, мы можем вызвать функцию регистрации события с помощью вызова lua_pcall
.Или ваша любимая функция вызова функции Lua;однако вы хотите сделать это.Lua будет использовать 3 параметра и саму функцию, чтобы они больше не находились в стеке.
И поскольку функция регистрации событий, вероятно, не возвращает значений, стек будет там, где он был, прежде чем мыпоместил функцию в стек (но не раньше, чем мы начали, в зависимости от того, сколько было выполнено очистки при получении функции).
После этого ваша функция C будет зарегистрирована в обработчике события для этого имени события.