Lua C 模块:关于包含成员的问题感到困惑。

我正在尝试注册一个 Lua C 模块,我需要像这样使用它。

local harfbuzz = require 'harfbuzz'

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

我的理解是,我应该创建一个新表并添加一个带有方法的元表,然后将该表作为顶级库表的成员 Blob

这是我在 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) {
  //问题:我应该在这里包含什么
}

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

  register_blob(L);

  luaL_setfuncs(L, lib_table, 0);

  return 1;
}
点赞
用户734069
用户734069

register_blob的功能实际上取决于new_blob需要做什么。它们两个是相互补充的。

根据您的用例,new_blob需要创建新对象,并将这些新对象的metatable成员设置为 blob_methods 表中的成员。因此,new_blob需要执行以下操作:

  1. 创建要返回的表/用户数据。
  2. 为该表/用户数据分配一个从 blob_methods 表的内容中构建的metatable。
  3. 对对象执行所有其他必要的初始化工作。
  4. 返回对象。

因此,您的 register_blob 代码需要构建您要在步骤2中使用的metatable,然后在 new_blob 可以轻松访问的地方存储它。但也需要在任何人都无法访问的位置存储。或者至少,除了C代码之外,没有其他人可以访问。

由于Lua的良好设计,它有一个存储这种精确数据的地方。它称为Lua注册表。注册表的作用像全局表一样。但只能从C中访问;Lua代码无法触及它(除非您使用调试库。或将注册表传递给Lua)。

我理解的流行方式是,每个C模块在注册表中都会有自己的表索引。因此,您的 luaopen_luaharfbuzz 函数将创建一个表并将其存储到注册表中的一个键中。该键可能是一个字符串,可能是您的模块命名的名称。并且您将所有私有内容放入该表中。

因此,您的 register_blob 函数需要执行以下操作:

  1. 创建将用作 blob 对象metatable的表。
  2. 使用 luaL_setfuncsblob_methods 设置到新创建的表中。
  3. 从注册表中获取 harfbuzz 表。
  4. 将新创建的表放入从注册表中的 harfbuzz 表的已知键中。

这样,new_blob 就知道到哪里获取要使用的metatable。

2015-12-02 15:11:54