无法使用 liblua.a 编译的 C 程序加载 C 动态库 (lua5.3)

我首先下载了 lua-5.3.5 并将源代码放在我的工作目录中,然后使用以下命令进行编译

make linux

这样我就在 ./lua-5.3.5/src 中得到了 liblua.a 和 lua 二进制文件。

接着我编写了一个 C 动态库,内容如下:

#include <stdio.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

static int l_sin(lua_State *L)
{
    double d = luaL_checknumber(L, 1);
    lua_pushnumber(L, sin(d));  /* 将结果推入栈中 */

    return 1;  /* 返回结果数量 */
}

static const struct luaL_Reg mylib[] = {
    {"mysin", l_sin},
    {NULL, NULL}
};

extern int luaopen_mylib(lua_State* L)
{
    luaL_newlib(L, mylib);

    return 1;
}

我使用以下命令进行编译:

gcc mylib.c -I ./lua-5.3.5/src -fPIC -shared -o mylib.so -Wall

如果我使用原始的 lua 二进制文件,则可以加载它

user00:lua/ $ ./lua-5.3.5/src/lua
Lua 5.3.5  版权所有 (C) 1994-2018 Lua.org, PUC-Rio
> require 'mylib'
table: 0xd13170
>

但是,如果我编写一个链接到 liblua.a 的 C 程序,它无法加载动态库。

#include <stdio.h>
#include <string.h>

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

int main(void){
    char buff[256];
    int error;
    lua_State *L  = luaL_newstate();
    luaL_openlibs(L);

    while(fgets(buff, sizeof(buff), stdin) != NULL)
    {
        error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
           lua_pcall(L, 0, 0 , 0);
        if(error)
        {
            fprintf(stderr, "%s", lua_tostring(L, -1));
            lua_pop(L, 1);
        }
    }

    lua_close(L);
    return 0;
}

编译:

gcc test01.c -L ./lua-5.3.5/src/ -llua -lstdc++ -o test01 -lm -ldl -I ./lua-5.3.5/src

运行:

user00:lua/ $ ./test01
require 'mylib'
从文件 './mylib.so' 加载模块 'mylib' 时出错:
    ./mylib.so: undefined symbol: luaL_setfuncs
点赞
用户107090
用户107090

你需要从你的可执行文件中导出 Lua API 函数。为此,请链接它与 -Wl,-E,就像 Lua 发行版的 Makefile 一样。

2019-12-24 14:59:30