如何在Lua C API中设置“require”以返回一个表/模块?

3
我希望能够通过C API单独添加可require的模块。
--lua.lua
local c_module = require("c_module")
c_module.doWork()

我需要使用哪些API函数才能实现这个功能?
1个回答

7
使用require加载共享库时,Lua会查找名为luaopen_<name>的函数(其中<name>是模块名称,用下划线替换点号,因此require "foo.bar"将查找luaopen_foo_bar,但短横线有特殊处理,请参阅Lua手册)。这个函数应该是一个常规的lua_CFunction,即它以lua_State*作为参数并返回intrequire调用此函数,并将包名作为参数,从函数中返回的值是require存储和返回的内容。以下是一个名为foo的模块示例:
static int bar(lua_State* L) {
    // ...
}

int luaopen_foo(lua_State* L) {
    lua_newtable(L); // Create package table

    // Push and assign each function
    lua_pushcfunction(L, &bar);
    lua_setfield(L, -2, "bar");

    // ...

    // Return package table
    return 1;
}

(这是针对Lua 5.1的,尽管5.2的等效代码应该非常相似,如果不是完全相同的话。还要确保luaopen_函数从共享库中导出。)
C加载器的完整行为可以在此找到:http://www.lua.org/manual/5.1/manual.html#pdf-package.loaders

如果没有名为foo.so/.dll的单独库,函数luaopen_foo必须被注册为cclosure作为package.preload.foo。这很简单:lua_getglobal(l, "package"); lua_pushstring(l, "preload"); lua_gettable(l, -2); lua_pushcclosure(l, luaopen_test, 0); lua_setfield(l, -2, "test"); lua_settop(l, 0);。这样可以直接在主程序中定义它。 - Appleshell
@Appleshell:或者,如果您不介意同时执行您的luaopen_test(),您可以使用Lua 5.2的luaL_requiref(),它将模块存储在package.loaded [modname]中。 - Niccolo M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接