简体   繁体   中英

Lua C modules: confused about including members

I am trying to register a Lua C module that I need to use like this.

local harfbuzz = require 'harfbuzz'

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

My understanding is that I should create a new table and add a metatable to it with the methods, and then add that table as a member Blob to the top-level lib table.

Here is the relevant snippet of code in my C file. I am not very sure what to include in the register_blob function. I tried a few things and they did not work.

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

What register_blob does really depends on what new_blob needs to do. The two feed into one another.

Given your use case, new_blob needs to create new objects, and those new objects have metatable members equal to your blob_methods table. So, what new_blob needs to do is:

  1. Create a table/userdata to be returned.
  2. Assign that table/userdata a metatable built from the contents of blob_methods table.
  3. Do whatever other initialization work is needed on the object.
  4. Return the object.

So what your register_blob code needs to do is build the metatable that you intend to use in step 2, then store it somewhere that new_blob can easily access it. But also somewhere that noone else can . Or at least, noone outside of C code.

Lua being well designed, it has a place for storing exactly this kind of data. It's called the Lua registry table . The registry acts like a global table. But it can only be access from C; Lua code can't touch it (well, unless you use the debug library. Or pass the registry table to Lua).

The idiomatic way (as I understand it) that the registry is used is that every C module stakes out its own table index in the registry. So your luaopen_luaharfbuzz function would create a table and store that into a key in the registry. The key would probably some string, likely named after your module. And you put all your private stuff into that table.

So your register_blob function would:

  1. Create the table that will be used as the metatable for blob objects.
  2. Use luaL_setfuncs to set the blob_methods into the newly created table.
  3. Get the harfbuzz table from the registry.
  4. Put the newly created table into a known key in the harfbuzz table from the registry.

That way, new_blob knows exactly where to go to get the metatable to use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM