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

LuaJIT FFI not loading symbols from executable

第一个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 函数。但是,有一个非常大的问题:加载的库使用与 运行 程序不同的内存 space。 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 从我的 运行 可执行文件加载符号?

-rdynamic 标志传递给 cc 解决了这个问题,允许 LuaJIT 从程序中 运行 ffi.C.* 函数。