LuaJIT FFI не загружает символы из исполняемого файла - PullRequest
3 голосов
/ 16 января 2020

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

1 Ответ

1 голос
/ 16 января 2020

Передача флага -rdynamic в cc устраняет проблему, позволяя LuaJIT запускать функции ffi.C.* из программы.

...