我正在尝试注册我需要使用的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;
}
答案 0 :(得分:2)
register_blob
的确取决于new_blob
需要做什么。两者相互馈送。
根据您的用例,new_blob
需要创建新对象,而这些新对象的metatable成员等于您的blob_methods
表。那么,new_blob
需要做的是:
blob_methods
table。那么你的register_blob
代码需要做的是构建你打算在步骤2中使用的元表,然后将它存储在new_blob
可以轻松访问它的地方。但也可以其他任何人。或者至少在C代码之外没有人。
Lua设计得很好,它有一个存储这种数据的地方。它被称为Lua registry table。注册表就像一个全局表。但它只能从C访问; Lua代码无法触摸它(好吧,除非你使用调试库。或者将注册表传递给Lua)。
使用注册表的惯用方法(据我所知)是每个C模块在注册表中标记自己的表索引。因此,您的luaopen_luaharfbuzz
函数将创建一个表并将其存储到注册表中的密钥中。密钥可能是一些字符串,可能以您的模块命名。然后你将所有私人资料放入该表中。
所以你的register_blob
函数会:
blob
对象的元表的表。luaL_setfuncs
将blob_methods
设置为新创建的表格。harfbuzz
表。harfbuzz
表中的已知密钥。这样,new_blob
确切地知道去哪里使用metatable。