我正在尝试注册一个我需要像这样使用的 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
需要做的是:
- 创建要返回的表/用户数据。
- 为该表/用户数据分配一个根据
blob_methods
表的内容构建的元表。 - 对对象执行任何其他需要的初始化工作。
- 返回对象。
因此,您的 register_blob
代码需要做的是构建您打算在第 2 步中使用的元表,然后将其存储在 new_blob
可以轻松访问的地方。但也是其他人无法的地方。或者至少,没有 C 代码之外的人。
Lua 设计得很好,它有一个地方可以存储这种数据。它叫做 Lua registry table .注册表就像一个全局表。但只能从C访问; Lua 代码无法触及它(好吧,除非你使用调试库。或者将注册表传递给 Lua)。
使用注册表的惯用方式(据我所知)是每个 C 模块在注册表中标出自己的表索引。因此,您的 luaopen_luaharfbuzz
函数将创建一个表并将其存储到注册表中的一个键中。 key 可能是一些字符串,可能以您的模块命名。然后您将所有私有(private)资料放入该表。
因此您的 register_blob
函数将:
- 创建将用作
blob
对象的元表的表。 - 使用
luaL_setfuncs
将blob_methods
设置到新创建的表中。 - 从注册表中获取
harfbuzz
表。 - 将新创建的表放入注册表中
harfbuzz
表中的已知键中。
这样,new_blob
就知道去哪里获取要使用的元表。
关于c - Lua C 模块 : confused about including members,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34045339/