Ответ 1
Кажется, что у каждого есть другой способ его достижения.
Это Луа; каждый делает это по-своему. Это лучшая сила и наибольшая слабость: язык предоставляет механизмы, а не политики.
Первое, что вам нужно сделать, это остановить использование luaL_register
. Да, я знаю, это удобно. Но вы хотите что-то особенное, а luaL_register
не поможет вам получить его.
Вы хотите создать таблицу, содержащую таблицу, содержащую одну или несколько функций. Итак... сделайте это.
Создайте таблицу.
lua_newtable(L);
Это было легко. Функция подталкивает таблицу к стеку, поэтому наш стек теперь имеет таблицу поверх нее. Это таблица, которую мы вернем.
Теперь нам нужно создать новую таблицу, чтобы войти в старую.
lua_newtable(L);
Опять же, легко. Затем мы хотим поместить функцию, которую хотим переместиться в эту таблицу в стеке.
lua_pushcfunction(L, hash_sha512);
Итак, в стеке есть три вещи: таблица назначения, таблица "хэш" (мы перейдем к "именованию" ее в секунду) и функции, которую мы хотим поместить в таблицу "хэш" .
Поэтому поместите функцию в хэш-таблицу.
lua_setfield(L, -2, "sha512");
Это занимает все, что находится поверх стека, и устанавливает его в поле с именем "sha512" в таблице по индексу -2 в стеке. Это где наш "хэш" стол. По завершении этой функции удаляет верхний элемент из стека. Это оставляет таблицу "хэш" наверху.
Мы можем повторить процесс для второй функции:
lua_pushcfunction(L, hash_sha384);
lua_setfield(L, -2, "sha384");
Теперь мы хотим поместить таблицу "hash" в таблицу, которую мы хотим вернуть. Это сделано достаточно легко с помощью другого вызова lua_setfield
:
lua_setfield(L, -2, "hash");
Помните: эта функция выполняет все, что находится поверх стека. На этом этапе таблица, которую мы хотим вернуть (которая будет наша таблица модулей), находится в стеке.
Мы можем повторить этот процесс для таблицы "hmac":
lua_newtable(L); //Create "hmac" table
lua_pushcfunction(L, hmac_sha512);
lua_setfield(L, -2, "sha512");
lua_pushcfunction(L, hmac_sha384);
lua_setfield(L, -2, "sha384");
lua_setfield(L, -2, "hmac"); //Put the "hmac" table into our module table
В таблице модулей теперь есть две записи: "хэш" и "hmac". Оба являются таблицами с двумя функциями в них.
Мы можем привязать его к глобальной таблице следующим образом:
lua_pushvalue(L, -1);
lua_setfield(L, LUA_GLOBALSINDEX, "polarssl");
Не каждый производитель модулей хочет это сделать. Некоторые предпочитают принуждать людей использовать синтаксис local polarssl = require "polarssl"
, чтобы избежать загрязнения глобального пространства имен. Это зависит от вас.
Но то, что вы должны сделать в любом случае, - это вернуть эту таблицу. Верните 1 из вашей функции luaopen
, чтобы Lua знал, что есть одно возвращаемое значение. Вышеуказанный вызов lua_pushvalue
существует с единственной целью копирования таблицы (помните: на таблицы ссылаются, поэтому, как и копирование указателя). Таким образом, когда вы используете lua_setfield
, копия удаляется из стека, в то время как оригинал остается использоваться как возвращаемое значение.