Вопросы по использованию FFI

Столкнулись с проблемой в использовании макросов? Здесь можно получить помощь.
User avatar
John Doe
Бюрократ
Posts: 13847
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Вопросы по использованию FFI

Post by John Doe »

FFI — одна из стандартных библиотек luajit.
Позволяет из Lua кода вызывать внешние C-функции и использовать структуры данных C.
В данной теме задаём вопросы по использованию FFI

Заготовка для документации: viewtopic.php?f=57&t=8418&p=147610#p147610

Примеры готовых скриптов:

Предупреждение: viewtopic.php?p=147610#p147610
Shmuel
Posts: 6834
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Вопросы по использованию FFI

Post by Shmuel »

Latest post of the previous page:

buniak_a_h wrote: Wed 28 Apr, 2021 22:08
citRiks wrote: Wed 28 Apr, 2021 18:57 было время когда я полагал что повторные require("ffi") делают какие-то проблемы.
Так действительно было, решение - добавление ffi в какой-то список - то ли в список package.preload, то ли в package.nounload (уже не помню). Потом что-то изменилось…
Повторные require("ffi") никогда не вызывали проблемы.
Проблемы возникают из-за того, что некоторые модули (например lpeg) не любят перезагрузки, видимо из-за внутренних дефектов.
Изменение в LuaMacro, о котором вы говорите, было в мае 2013, но оно не имело отношения к require "ffi".
User avatar
buniak_a_h
Posts: 4259
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 644 times
Contact:

Вопросы по использованию FFI

Post by buniak_a_h »

Shmuel, Вам, конечно, виднее. Но я помню, что у меня некоторые скрипты валились при повторном запуске (вместе с ФАРом), и, чтобы предотвратить беду, я делал так: _G.BAX_FFI = _G.BAX_FFI or require"ffi"
Last edited by buniak_a_h on Wed 28 Apr, 2021 22:39, edited 1 time in total.
Shmuel
Posts: 6834
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Вопросы по использованию FFI

Post by Shmuel »

buniak_a_h, я уже сам начал сомневаться, но о проблеме с повторным вызовом require 'ffi' не помню, а появление package.nounload имело своей первопричиной lpeg (и до сих пор LuaMacro содержит package.nounload.lpeg=true).
Если вы предоставите данные о версии Фара и скрипт, приводивший к падению, то я после проверки могу охотно признать свою неправоту.
User avatar
buniak_a_h
Posts: 4259
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 644 times
Contact:

Вопросы по использованию FFI

Post by buniak_a_h »

1.
Shmuel wrote: Wed 28 Apr, 2021 22:51 Если вы предоставите данные о версии Фара
4 года прошло …
2.
Shmuel wrote: Wed 28 Apr, 2021 22:51 скрипт, приводивший к падению
Любой, использовавший ffi. Первый раз наткнулся в копировании со временной панели с сохранением структуры каталогов. Потом - в ClickToTitleDir
Потом я узнал про package.nounload и вставил package.nounload.ffi = true в _macroinit.lua. Но давно это было.
Так что доказательств нету, каждый может верить во что хочет. Тем более, от этого уже ничего не зависит.
Last edited by buniak_a_h on Thu 29 Apr, 2021 00:40, edited 1 time in total.
Shmuel
Posts: 6834
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Вопросы по использованию FFI

Post by Shmuel »

Ну я не поленился, взял ваш скрипт ClickToTitleDir и проверил на старых версиях Фара (включая билд 4807 от 06.10.2016). Ничего не падает, в т.ч. при многократной перезагрузке макросов.
Теперь очередь за вами - продемонстрируйте падение от require 'ffi' или научите, как его добиться.
User avatar
buniak_a_h
Posts: 4259
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 644 times
Contact:

Вопросы по использованию FFI

Post by buniak_a_h »

Shmuel, я не настаиваю (в смысле - не упираюсь). Помню, что с повторным запуском некоторых скриптов, содержащих ffi, была проблема. Возможно, дело было не в самом require, а в попытке переопределения констант, которые уже были определены при прошлом запуске.
Сейчас у меня остался только один "лишний" элемент этой таблицы: package.nounload.ljsqlite3=true.
Ещё, как оказалось, я убирал require"ffi" в ту функцию, которая вызывалась из action - так не вылетало. А если require было вне функций -вылетало. Возможно, после перезагрузки макросов.
Короче, подробностей я не помню. Помню, что проблемы были именно с ffi и именно с повторным выполнением скрипта - не макроса. Меня тогда ещё убило: в макросе всё ок, а в скрипте при втором выполнении вылет.
User avatar
John Doe
Бюрократ
Posts: 13847
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Вопросы по использованию FFI

Post by John Doe »

buniak_a_h wrote: Thu 29 Apr, 2021 04:18 Короче, подробностей я не помню.
А без подробностей всё это лишь информационный шум.
Тему через время почищу.
https://t.me/FarManager — Telegram чат
User avatar
John Doe
Бюрократ
Posts: 13847
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Вопросы по использованию FFI

Post by John Doe »

citRiks wrote: Wed 28 Apr, 2021 20:45 Это что-ли? :)
(facepalm)

Вот тут ответы на основные вопросы: viewtopic.php?f=57&t=8418&p=147610#p147610
(если чего-то нет, то добавлю).

Специально для вас показываю пальцем: пункт 2.
Shmuel wrote: Wed 28 Apr, 2021 21:31 - Модули проконтролировать на отсутствие дубликатных вызовов.
Я что-то пропупустил и pcall уже не достаточно?
https://t.me/FarManager — Telegram чат
Shmuel
Posts: 6834
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Вопросы по использованию FFI

Post by Shmuel »

John Doe wrote: Thu 29 Apr, 2021 07:23 Я что-то пропупустил и pcall уже не достаточно?
Решение, использующее pcall, обладает тем недостатком, что в блоке определений (аргументе ffi.cdef) не будут обработаны определения, следующие после ошибочного. То есть pcall требует мелкой грануляции определений (в идеале - по одному вызову ffi.cdef на определение).
А ещё pcall маскирует ошибки, что не есть хорошо.
То решение, что я предложил выше, свободно от этих недостатков.
User avatar
John Doe
Бюрократ
Posts: 13847
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Вопросы по использованию FFI

Post by John Doe »

Shmuel wrote: Thu 29 Apr, 2021 08:21 То решение, что я предложил выше, свободно от этих недостатков.
Оно применимо только если не использовать стороннего кода, что вряд-ли стоит рекомендовать на форуме где люди как раз им и делятся.
Shmuel wrote: Thu 29 Apr, 2021 08:21 То есть pcall требует мелкой грануляции определений (в идеале - по одному вызову ffi.cdef на определение).
Это факт. Но это несложно (проще чем например по модулям делить).
Shmuel wrote: Thu 29 Apr, 2021 08:21 А ещё pcall маскирует ошибки, что не есть хорошо.
В случае cdef это непринципиально, поскольку если там синтаксическая ошибка, то определение вообще не сработает (что сразу всплывёт и так), а другие типы cdef всё равно не обрабатывает.
https://t.me/FarManager — Telegram чат
User avatar
Smitis
Posts: 1709
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 23 times
Been thanked: 55 times

Вопросы по использованию FFI

Post by Smitis »

citRiks wrote: Wed 28 Apr, 2021 18:57 Если у вас есть какие-то идеи или решения для этого, то буду рад услышать конечно
Уберите _CREATE_THREAD_DEBUG_INFO, _LARGE_INTEGER и прочие везде после struct
Разум когда-нибудь победит.
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Вопросы по использованию FFI

Post by citRiks »

Всем спасибо за ответы, особенно @Smitis , надеюсь что сегодня доберусь протестировать
John Doe wrote: Thu 29 Apr, 2021 07:23 Специально для вас показываю пальцем: пункт 2.
это понятно что "низзя",
я просто думал что можно написать что-нибудь проверящее наличие желаемой декларации,
и если она уже есть, то не декларировать еще раз.
Вместе с этим, признаю что моя это идея слишком сложна к воплощению, скорее невозможна.
Так например, декларация с определенным именем может быть уже и есть,
но может быть отлична в деталях каких-то, или даже быть совсем другой
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Вопросы по использованию FFI

Post by citRiks »

John Doe wrote: Thu 29 Apr, 2021 07:23 Вот тут ответы на основные вопросы: viewtopic.php?f=57&t=8418&p=147610#p147610
привел функцию safe_cdef(...) к такому виду:

Code: Select all

if not	_G.ffi
then	_G.ffi = require("ffi")
end
local ffi = _G.ffi

local function fnc_ffi_cdef_safe(def_txt, silent)
	local res, err = pcall(ffi.cdef, def_txt)
	if not	res 
	and not silent
	then	local dbginf = debug.getinfo(2, "nSl")
		local msg = string.format("%s:%d\n---\n%s\n---\n%s", dbginf.short_src, dbginf.currentline, err, def_txt)
		far.Message(msg, "FFi cDef load error", nil, "wl")
	end
	return res, err
end

fnc_ffi_cdef_safe([[
static const ULONG SEE_MASK_NO_CONSOLE = 0x00008000;
]])
fnc_ffi_cdef_safe([[
//https://docs.microsoft.com/en-us/windows/console/console-selection-info-str
typedef struct _CONSOLE_SELECTION_INFO {
  DWORD      dwFlags;
  COORD      dwSelectionAnchor;
  SMALL_RECT srSelection;
} CONSOLE_SELECTION_INFO, *PCONSOLE_SELECTION_INFO;
]])
.. чтобы было так:
image.png
image.png (7.24 KiB) Viewed 6432 times
User avatar
John Doe
Бюрократ
Posts: 13847
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Вопросы по использованию FFI

Post by John Doe »

citRiks wrote: Sat 01 May, 2021 08:39 это понятно что "низзя",
Неправильно понимаете.
Пере-определение невозможно, верно.

И тем не менее иметь независимые определения в каждом скрипте - в наших условиях необходимо.
Модуль ffi не рассчитан на такое использование, поэтому чтобы подавить ошибки мы используем конструкции вроде safe_cdef.
Используя которые мы берём на себя обязательство самостоятельно контроллировать корректность, и не создавать "несовместимых" определений.
https://t.me/FarManager — Telegram чат
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Вопросы по использованию FFI

Post by citRiks »

Smitis wrote: Thu 29 Apr, 2021 09:16
citRiks wrote: Wed 28 Apr, 2021 18:57Если у вас есть какие-то идеи или решения для этого, то буду рад услышать конечно
Уберите _CREATE_THREAD_DEBUG_INFO, _LARGE_INTEGER и прочие везде после struct
Т.е. вместо:

Code: Select all

typedef struct _CREATE_THREAD_DEBUG_INFO {
    HANDLE hThread;
    LPVOID lpThreadLocalBase;
    LPTHREAD_START_ROUTINE lpStartAddress;
} CREATE_THREAD_DEBUG_INFO, *LPCREATE_THREAD_DEBUG_INFO;
.. должно быть так:

Code: Select all

typedef struct _CREATE_THREAD_DEBUG_INFO {
    HANDLE hThread;
    LPVOID lpThreadLocalBase;
    LPTHREAD_START_ROUTINE lpStartAddress;
}
?
Post Reply

Return to “Нужна помощь”