Lua 支持通过加载外部 so 库扩展自身功能,so 库可以使用 C/C++ 语言开发,同时必须按 Lua 接口规范开发。

示例

mylib.c:

#include <lua.h>     /* Always include this */
#include <lauxlib.h> /* Always include this */
#include <lualib.h>  /* Always include this */

#include <dirent.h>
#include <string.h>
#include <errno.h>

static int hello(lua_State *L)           /* Internal name of func */
{
    lua_pushstring(L, "Hello, Lua.");    /* Push the return */

    return 1;                            /* One return value */
}

static int l_dir(lua_State *L)           /* Internal name of func */
{
    DIR *dir;
    struct dirent *entry;
    int i;
    const char *path = luaL_checkstring(L, 1); /* Get the single string arg */

    /* open directory */
    dir = opendir(path);
    if (dir == NULL) {  /* error opening the directory? */
        lua_pushnil(L);  /* return nil and ... */
        lua_pushstring(L, strerror(errno));  /* error message */

        return 2;  /* number of results */
    }

    /* create result table */
    lua_newtable(L);
    i = 1;
    while ((entry = readdir(dir)) != NULL) {
        lua_pushnumber(L, i++);  /* push key */
        lua_pushstring(L, entry->d_name);  /* push value */
        lua_settable(L, -3);
    }

    closedir(dir);

    return 1;  /* table is already on top */
}

static const struct luaL_Reg mylib [] = {
    {"dir", l_dir},
    {NULL, NULL} /* sentinel */
};

int luaopen_mylib (lua_State *L)
{
    
    //export function
    lua_register(
            L,               /* Lua state variable */
            "hello",         /* func name as known in Lua */
            hello            /* func name in this file */
        );  


    //export lib
    
    //luaL_openlib(L, "mylib", mylib, 0);

    //luaL_newlibtable(L, mylib);
    //luaL_setfuncs(L, mylib, 0);

    luaL_newlib(L, mylib);

    return 1;
}

编译:

gcc -Wall -shared -fPIC -o mylib.so mylib.c

mylib-demo.lua:

local mylib = require "mylib"

for k, v in ipairs(mylib.dir (".")) do
    print(k, v)
end

print(hello())

执行输出:

1   mylib.so
2   .
3   ..
4   mylib-demo.lua
5   mylib.c
Hello, Lua.

Lua 官方的文档内容有些是错误或过期的,使得走了一些弯路。如官方文档在注册 Library 使用的接口是:

...
luaL_openlib(L, "mylib", mylib, 0);
...

上面的代码在我的环境是编译不通过,官方文档和网上都有这样的用法,而我用的是最新版本的 Lua,已经不支持这种写法。

诸如这样的问题有好几个,不一一描述,具体可以读一下程序,程序是参考了官方的文档和一些网上的文章修改而来,在我的开发机上是编译执行通过的。

相关链接