1

EDIT: Nearly got the answer, I just dont completely understand it, see last paragraph.

I try to build a shared lua library and use it within a larger project. When calling the script which loads the shared library from shell everything works. However, when I wrap the script within another shell, I get a runtime error when loading the library. Dependent on the script it is just any call to a lua function from c (i.e. lua_pushnumber). Here is a minimal example.

totestlib.cpp:

extern "C" {
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
}
int init(lua_State *L) {
    lua_toboolean(L, -1);
    return 0;
}
static const struct luaL_Reg testlib[] = {
    {"init", init},
    {NULL, NULL}
};
extern "C"
int luaopen_libtotestlib(lua_State *L) {
    luaL_newlib(L, testlib);
    return 1;
}

Compiled with: g++ -shared -fPIC -I./lua-5.4.4/src -L./lua-5.4.4/src totestlib.cpp -o libtotestlib.so

testlib.lua (testing shared library):

testlib.lua
print("start")
testlib = require("libtotestlib")
print("done")
testlib.init(true)
print("called")

Calling the lua script using ./lua-5.4.4/src/lua testlib.lua works. Everything is printed. Wrapping script in the following c++ code does not work:

call_testlib.cpp

extern "C" {
    #include <lua.h>
    #include <lauxlib.h>
    #include <lualib.h>
}
#include <unistd.h>
static lua_State *L;
int main(int argc, char *argv[]) {
    L = luaL_newstate();
    luaL_openlibs(L);
    int tmp = luaL_loadfile(L, "testlib.lua");
    if(tmp != 0) {
        return 1;
    }
    tmp = lua_pcall(L, 0, 0, 0);
    if(tmp != 0) {
        printf("error pcall\n");
        return 1;
    }
}

Compiled with g++ call_testlib.cpp -o ./call_testlib -I./lua-5.4.4/src -L./lua-5.4.4/src -llua it prints "error pcall". If I print the error message on the lua stack, I get:

string  error loading module 'libtotestlib' from file './libtotestlib.so':
    ./libtotestlib.so: undefined symbol: luaL_checkversion_

In this case the undefined symbol is luaL_checkversion_ (which I dont call myself), but with other scripts it is usually the first lua_... function that I call.

I have tried several things to fix this. For example, linking -llua when compiling the shared library, but this does not work (and should not be the problem as calling the script itself works). I also tried to load preload the library from c++ (as done in this question) instead of from lua, but I guess it does not really make a difference and I am getting the same error. I also uninstalled all lua versions from my path to make sure I always use the same version.

What is the difference between calling the script directly from shell and calling it inside a c function? Am I doing something wrong?

EDIT: Nearly got the answer. When using MYCFLAGS= -fPIC when compiling lua I can link lua to the shared library. At least this one works, but does not seem like a good solution to me and does not really answer my question: Why can lua itself (from shell) somehow add these symbols to the library while the wrapped c version can not? Additionally, my program has lua once linked in the shared library and once in the compiled C++ project (not optimal imo).

user84037
  • 73
  • 2
  • 7
  • 1
    The host program needs to expose the Lua API to shared libraries. On Linux, you need to build `call_testlib` with `-Wl,-E -ldl` to export the names in the Lua API to the shared library. – lhf Jan 18 '23 at 11:03
  • Also, don't link the Lua library to the shared library. – lhf Jan 18 '23 at 11:05
  • @lhf Thank you! Thats basically the answer I was looking for. Will take a look at what these flags actually mean. Compiling works now without linking lua to the shared library. – user84037 Jan 18 '23 at 18:52
  • See also the last paragraph of this section: https://web.tecgraf.puc-rio.br/~lhf/ftp/lua/install.html#adding – lhf Jan 18 '23 at 21:00
  • Possible duplicate of https://stackoverflow.com/questions/59468871/cannot-load-c-dynamic-library-with-c-program-compile-with-liblua-a-lua5-3 and https://stackoverflow.com/questions/3107102/why-does-lua-report-that-lua-pushlstring-is-undefined/3107908#3107908 – lhf Jan 18 '23 at 21:02

0 Answers0