Первый 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
Как мне заставить FFI LuaJIT загружать символы из моего исполняемого исполняемого файла?