第一个 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内部运行的可执行文件的控制台子系统。控制台缓冲区被存储为一个全局的(外部)字符串数组,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从我的正在运行的可执行文件中加载符号?
objdump -t ./build/a.out
命令,查看该符号是否存在于可执行文件中 :) - DarkWiiPlayernm --defined-only
的作用。这里是objdump -t build/a.out| grep printc
的输出结果:000000000001abd1 g F .text 0000000000000179 printc
。 - Accumulator