--- title: LuaJIT FFI и нативная граница summary: Подготовка типов, совместимость ABI и причины не переносить найденную сигнатуру между сборками вслепую. section: native kind: guide status: reference tags: ["ffi","LuaJIT","C++","native","ABI"] sources: ["https://github.com/eg3r/X4Native"] --- ## Когда нужен нативный слой Для изменения XML-параметров или обычного окна он обычно не нужен. Переходите к FFI или собственной DLL, когда задачу нельзя полностью решить доступным MD и Lua UI. Различайте встроенные Lua-функции, вызовы экспортов через FFI и загрузку собственного Lua C-модуля. Это разные интерфейсы с разными контрактами. ## Объявление ABI Пример формы объявления, используемой с соответствующей сборкой игры: ```lua local ffi = require("ffi") if ffi.cdef then pcall(ffi.cdef, [[ bool IsGamePaused(void); bool IsStartmenu(void); ]]) end ``` Успех `cdef` не доказывает наличие экспорта. `pcall` не делает неверную сигнатуру безопасной. Сверяйте типы, соглашение о вызовах и поддержку в своей версии X4. ## Сторонние компоненты X4Native - отдельная библиотека со своим загрузчиком и ABI. Она не становится обязательной зависимостью любого Lua-мода. Если используете её, объявите зависимость и проверяйте совместимость. Защищённый режим UI также влияет на доступные механизмы загрузки. Не советуйте отключать его как первый шаг для обычной правки данных. ## Типы значений Указатель, `uint64_t` и Lua number не взаимозаменяемы. Читайте [точность ID](wiki:ids-and-precision) до сериализации или передачи значений между языками. Прямые смещения памяти ещё сильнее зависят от сборки. Минимальное исследование сначала должно безопасно подтвердить чтение и идентичность объекта, затем - изменяющий эффект.