c - Lua C 模块 : confused about including members

标签 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;
}

最佳答案

register_blob 的作用实际上取决于new_blob 需要做什么。两者相辅相成。

鉴于您的用例,new_blob 需要创建新对象,并且这些新对象具有与您的 blob_methods 表相同的元表成员。所以,new_blob 需要做的是:

  1. 创建要返回的表/用户数据。
  2. 为该表/用户数据分配一个根据 blob_methods 表的内容构建的元表。
  3. 对对象执行任何其他需要的初始化工作。
  4. 返回对象。

因此,您的 register_blob 代码需要做的是构建您打算在第 2 步中使用的元表,然后将其存储在 new_blob 可以轻松访问的地方。但也是其他人无法的地方。或者至少,没有 C 代码之外的人。

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

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

因此您的 register_blob 函数将:

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

这样,new_blob 就知道去哪里获取要使用的元表。

关于c - Lua C 模块 : confused about including members,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34045339/

相关文章:

C - 代码块 - 设置程序参数

c - 我如何使用其他变量打印 ascii 代码?

c++ - 如何为 windows 编写 posix waitpid() 模拟?

module - 什么是 Lua 模块的好存储库?

sorting - 从表中找到最小值的最佳方法?

c - unix socket send() 成功,但 recv() 失败

c - 为结构中的数组分配内存(在 C 中)

multithreading - 如何检测和快速完成响应时间太长的lua功能?

c++ - 从 C++ 访问表中的 Lua 表

c++ - Lua loadfile() 无法在同一目录中找到文件