Lua C模块:对包含成员感到困惑

时间:2015-12-02 14:33:46

标签: c lua

我正在尝试注册我需要使用的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;
}

1 个答案:

答案 0 :(得分:2)

register_blob的确取决于new_blob需要做什么。两者相互馈送。

根据您的用例,new_blob需要创建新对象,而这些新对象的metatable成员等于您的blob_methods表。那么,new_blob需要做的是:

  1. 创建要返回的表/ userdata。
  2. 将该表/ userdata分配为根据blob_methods table。
  3. 的内容构建的元表
  4. 在对象上执行其他任何初始化工作。
  5. 返回对象。
  6. 那么你的register_blob代码需要做的是构建你打算在步骤2中使用的元表,然后将它存储在new_blob可以轻松访问它的地方。但也可以其他任何人。或者至少在C代码之外没有人。

    Lua设计得很好,它有一个存储这种数据的地方。它被称为Lua registry table。注册表就像一个全局表。但它只能从C访问; Lua代码无法触摸它(好吧,除非你使用调试库。或者将注册表传递给Lua)。

    使用注册表的惯用方法(据我所知)是每个C模块在注册表中标记自己的表索引。因此,您的luaopen_luaharfbuzz函数将创建一个表并将其存储到注册表中的密钥中。密钥可能是一些字符串,可能以您的模块命名。然后你将所有私人资料放入该表中。

    所以你的register_blob函数会:

    1. 创建将用作blob对象的元表的表。
    2. 使用luaL_setfuncsblob_methods设置为新创建的表格。
    3. 从注册表中获取harfbuzz表。
    4. 将新创建的表放入注册表中harfbuzz表中的已知密钥。
    5. 这样,new_blob确切地知道去哪里使用metatable。