2015-12-02 2 views
1

Я пытаюсь зарегистрировать модуль Lua C, который мне нужно использовать следующим образом.Модули Lua C: путают о включении членов

local harfbuzz = require 'harfbuzz' 

-- initialize blob 
local blob = harfbuzz.Blob.new(…) 
print(blob:length()) 

Я понимаю, что я должен создать новую таблицу и добавить метатаблицу к нему с методами, а затем добавить эту таблицу в качестве члена Blob к Lib таблицы верхнего уровня.

Вот соответствующий фрагмент кода в моем файле C. Я не очень уверен, что включить в функцию register_blob. Я попробовал несколько вещей, и они не сработали.

static const struct luaL_Reg blob_methods[] = { 
    { "length", blob_length }, 
    {"__gc", blob_destroy }, 
    { NULL, NULL }, 
}; 

static const struct luaL_Reg blob_functions[] = { 
    { "new", blob_new }, 
    { NULL, NULL } 
}; 

static const struct luaL_Reg lib_table [] = { 
    {"version", get_harfbuzz_version}, 
    {NULL, NULL} 
}; 

int register_blob(lua_State *L) { 
    // QUESTION: What should I include here 
} 

int luaopen_luaharfbuzz (lua_State *L) { 
    lua_newtable(L); 

    register_blob(L); 

    luaL_setfuncs(L, lib_table, 0); 

    return 1; 
} 

ответ

2

register_blob Что делает действительно зависит от того, что new_blob нужно сделать. Эти два человека вступают друг в друга.

С учетом вашего использования, new_blob необходимо создать новые объекты, и эти новые объекты имеют металируемые элементы, равные вашей таблице blob_methods. Итак, что необходимо сделать new_blob:

  1. Создать таблицу/данные для возврата.
  2. Назначьте таблицу/userdata метатемой, построенной из содержимого таблицы blob_methods.
  3. Выполняйте любые другие операции инициализации на объекте.
  4. Верните объект.

Так что ваш register_blob код нужно сделать, это построить метатаблицу, которые вы собираетесь использовать на шаге 2, а затем сохранить его где-нибудь, что new_blob может легко получить доступ к нему. Но и где-то, что никто не может. Или, по крайней мере, никто из C-кода.

Lua, хорошо спроектированный, имеет место для хранения точно таких данных. Это называется Lua registry table. Реестр действует как глобальная таблица. Но это может быть только доступ с C; Код Lua не может касаться его (ну, если вы не используете библиотеку отладки или не передаете таблицу реестра Lua).

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

register_blob Так что ваша функция будет:

  1. Создать таблицу, которая будет использоваться в качестве метатаблицы для blob объектов.
  2. Используйте luaL_setfuncs, чтобы установить blob_methods во вновь созданный стол.
  3. Получить таблицу harfbuzz из реестра.
  4. Поместите вновь созданную таблицу в известный ключ в таблице harfbuzz из реестра.

Таким образом, new_blob точно знает, куда идти, чтобы получить возможность использования метаданных.

+0

Спасибо, что написали такой всеобъемлющий ответ. – vyom

+0

Конечно, вы можете передать реестр Lua: 'lua_pushvalue (L, LUA_REGISTRYINDEX)'. Это то, что 'debug.getregistry' делает ... – siffiejoe

+0

@siffiejoe: Отмечено и исправлено. –

Смежные вопросы