LuaJIT FFI未从可执行文件中加载符号

第一个Lua代码:

local ffi = require "ffi"

ffi.cdef[[
void printc(const char *fmt, ...);
]]
ffi.C.printc("Hello world")

无法工作。错误信息:

boot.lua:6: /usr/lib64/libluajit-5.1.so.2: undefined symbol: printc

但实际上,该符号确实在LuaJIT所在的可执行文件内定义了(函数声明是从C中复制过来的):

$ nm --defined-only build/a.out | grep printc
00000000000650c1 T printc

我最初的解决方案是使用与可执行文件相同的符号构建共享库并在LuaJIT中加载它:

$ cc -fPIC -shared $LDFLAGS $OFILES -o build/a.so

新的Lua代码:

local ffi = require "ffi"
lib = ffi.load("./build/a.so")
ffi.cdef[[
void printc(const char *fmt, ...);
]]
lib.printc("Hello world")

这使我可以调用printc函数。但存在一个非常大的问题:加载的库使用与正在运行的程序不同的内存空间。“lib.printc("Hello world")”正在写入的缓冲区不是LuaJIT正在运行的程序所使用的同一缓冲区。它的作用就像与完全不同的进程进行交互。

printc应该将数据打印到LuaJIT所在的可执行文件的控制台子系统中。控制台缓冲区被存储为全局( extern)字符串数组,printc向其中写入。LuaJIT通过加载a.so获取的全局控制台缓冲区,指向与正在运行的a.out程序的全局控制台缓冲区不同的内存地址。

因此,这不是可行的解决方案。我不知道现在该怎么办。这些符号作为我的可执行文件的一部分被导出,但LuaJIT不加载它们。我也不能ffi.load我的可执行文件:

lib = ffi.load("./build/a.out")

boot.lua:2: ./build/a.out: cannot dynamically load position-independent executable

我该如何让LuaJIT FFI从我的运行中的可执行文件中加载符号?

点赞
用户3995239
用户3995239

cc 传递 -rdynamic 标志可以解决此问题,允许 LuaJIT 运行程序中的 ffi.C.* 函数。

2020-01-16 17:46:25