Кажется, что у каждого свой способ достижения этого.
Это Луа; каждый делает это по-своему. Это самая сильная и слабая сторона Lua: язык предоставляет механизмы, а не политики .
Первое, что вам нужно сделать, это прекратить использовать luaL_register
. Да, я знаю, это удобно. Но вы хотите что-то особенное, и luaL_register
не поможет вам получить это.
Вам нужно создать таблицу, содержащую таблицу, содержащую одну или несколько функций. Итак ... сделай это.
Создать таблицу.
lua_newtable(L);
Это было легко. Функция помещает таблицу в стек, поэтому теперь в нашем стеке есть таблица. Это таблица, которую мы вернем.
Теперь нам нужно создать новую таблицу, чтобы перейти внутрь старой.
lua_newtable(L);
Опять просто. Далее мы хотим поместить функцию, которую мы хотим поместить в эту таблицу, в стек.
lua_pushcfunction(L, hash_sha512);
Таким образом, в стеке есть три вещи: таблица назначения, таблица «hash» (мы будем «называть» ее через секунду) и функция, которую мы хотим поместить в таблицу «hash».
Итак, поместите функцию в хеш-таблицу.
lua_setfield(L, -2, "sha512");
Это берет все, что находится на вершине стека, и устанавливает его в поле с именем "sha512" в таблице с индексом -2 в стеке. Вот где находится наш "хэш" стол. После завершения этой функции она удаляет верхний элемент из стека. Это оставляет "хэш" таблицу наверху.
Мы можем повторить процесс для второй функции:
lua_pushcfunction(L, hash_sha384);
lua_setfield(L, -2, "sha384");
Теперь мы хотим поместить «хеш-таблицу» в таблицу, которую хотим вернуть. Это достаточно легко сделать с помощью другого 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
В таблице модуля теперь есть две записи: "hash" и "hmac". Обе таблицы с двумя функциями.
Мы можем вставить его в глобальную таблицу следующим образом:
lua_pushvalue(L, -1);
lua_setfield(L, LUA_GLOBALSINDEX, "polarssl");
Не каждый производитель модулей хочет это сделать. Некоторые предпочитают заставлять людей использовать синтаксис local polarssl = require "polarssl"
, чтобы не загрязнять глобальное пространство имен. Вам решать.
Но в любом случае вы должны вернуть эту таблицу. Верните 1 из вашей функции luaopen
, чтобы Lua знала, что есть одно возвращаемое значение. Вызов lua_pushvalue
выше существует только для копирования таблицы (помните: на таблицы ссылаются, так что это похоже на копирование указателя). Таким образом, когда вы используете lua_setfield
, копия удаляется из стека, а оригинал остается для использования в качестве возвращаемого значения.