第一个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从正在运行的可执行文件中加载符号?
最佳答案
将-rdynamic
标志传递给cc
可解决此问题,从而使LuaJIT可以从程序中运行ffi.C.*
函数。