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

Столкнулись с проблемой в использовании макросов? Здесь можно получить помощь.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 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
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

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

Post by John Doe »

Latest post of the previous page:

Shmuel wrote:Можно было бы при этом сделать и модуль winapiex (т.е. "extended").
Предвижу сложности. Возьмём такой сценарий.
1) Какой-то скрипт не использует модуль winapiex.lua, но для своих нужд определяет тип "TOKEN_PRIVILEGES"
2) Другой скрипт пытается после этого загрузить winapiex.lua, но обламывается, т.к. ffi не даёт переопределить.

И pcall в данном случае не особо поможет

P.S.
Насколько я могу судить, облом только при попытке переопределить структуры.
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

John Doe wrote:Хотя... Предвижу сложности. Возьмём такой сценарий.
......
Либо определения оба корректны, тогда проблем нет, либо (в крайне редких случаях) можно переименовать имя структуры.

Если быть последовательными, то кроме двух вышеупомянутых файлов модулями нужно сделать и panelsort.lua, и moonscript.lua. Их все можно поместить в папку LuaMacro\modules, а плагин будет добавлять эту папку в package.path.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

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

Post by John Doe »

Либо определения оба корректны, тогда проблем нет, либо (в крайне редких случаях) можно переименовать имя структуры.
Проблема не в этом.

Любое единичное переопределение можно завернуть в pcall, как мы и делаем сейчас.
Модуль же содержит множество определений, его в pcall не завернёшь.

Устранение конфликтов переименованием структур - это какая-то ерунда, т.к. во-первых от имён структур могут зависить другие определения.
И во-вторых, конфликт в своём скрипте я устраню как-нибудь. Но если я скачал скрипт с форума, то ковырять его как-то вообще нехорошо.
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

John Doe wrote:Любое единичное переопределение можно завернуть в pcall, как мы и делаем сейчас.
Модуль же содержит множество определений, его в pcall не завернёшь.
Внутри модуля вполне можно использовать pcall, многократно.

Если кто-то выложит для скачивания модуль или скрипт, несовместимый со стандартной поставкой Фара, это его проблемы.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

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

Post by John Doe »

Shmuel wrote:Если кто-то выложит для скачивания модуль или скрипт, несовместимый со стандартной поставкой Фара, это его проблемы.
Не всё так просто.
Скрипт будет совместим со стандартной поставкой.
И даже с другими скриптами, использующими модуль, если они выполняются ДО него.
Shmuel wrote:Внутри модуля вполне можно использовать pcall, многократно.
Можно, но при большом количестве структур - это будет громоздко и медленно.

Любую проблему можно решить, я понимаю. Но зачем создавать её искуственно?
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

John Doe wrote:Не всё так просто.
Скрипт будет совместим со стандартной поставкой.
И даже с другими скриптами, использующими модуль, если они выполняются ДО него.
Если скрипт определяет те же структуры, что есть в стандартной поставке, то он несовместим, вот и всё.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

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

Post by John Doe »

Сегодня совместим, а завтра мы добавили в поставку новые структуры, и стал несовместим. Нехорошо.
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

John Doe wrote:Сегодня совместим, а завтра мы добавили в поставку новые структуры, и стал несовместим. Нехорошо.
Это не проблема, если сторонние скрипты будут вызывать require "winapi" перед своими ffi-определениями. Ошибка сразу и вылезет.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

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

Post by John Doe »

Не вылезет, ведь свои определения завёрнуты в pcall.

Но да, если обязать всех делать require ("winapi") до собственных деклараций, то это поможет решить проблему. Административно.
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

Ситуация на данный момент мало чем отличается от всего, что вы описываете.
-- Два разных скрипта могут определить конфликтующие декларации.
-- Скрипт может завернуть свою конфликтующую с фаровской декларацию в pcall, и это пройдёт незамеченным.
-- "Административно" - никто не запрещает пользоваться исключительно глобальными переменными с короткими именами, никто не запрещает сделать _G.far=45 и т.д.
Last edited by Shmuel on Thu 19 Jun, 2014 20:37, edited 1 time in total.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

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

Post by John Doe »

Shmuel wrote:-- Два разных скрипта могут определить конфликтующие декларации.
Это у нас уже принято решать обёртками вокруг ffi.cdef.
Реальная проблема будет только если декларации окажутся несовместимыми. Это возможно, но сравнительно маловероятно.
Shmuel wrote:-- Скрипт может завернуть свою конфликтующую с фаровской декларацию в pcall, и это пройдёт незамеченным.
Это вообще крайне маловероятно, в фаре только winapi/farapi, и пользовательская декларация может оказаться несовместимой разве что в результате ошибки пользователя.
Shmuel wrote:И т.д. и т.п.
Предлагаю рассмотреть поимённо.
Shmuel wrote:Ситуация на данный момент мало чем отличается от всего, что вы описываете.
На данный момент фаровские определения грузятся первыми.
Из этого следует, что в случае конфликта пострадает только сам конфликтующий скрипт.

Если же фаровские определения станут модулями, то в случае конфликта наоборот, пострадают все прочие скрипты, честно использующие require в начале.
Причём сообщение об ошибке вообще не будет указывать на реальный источник конфликта.
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

1. Отредактировал чуть сообщение выше
2. Устал, больше в подобные дискуссии постараюсь не ввязываться
3. Сделаю, как сочту нужным
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

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

Post by John Doe »

Вот ещё информация к размышлению:
ffi.cdef выдаёт ошибку в случае попытки повторного объявления структуры с тем же именем типа.
Но если объявить структуру с другим именем типа (struct NewName {...}), или без имени (struct {...}), то никаких сообщений об ошибке не будет.
Может быть это стоит использовать? Ведь по факту в winapi не используются имена типов структур, а типы определяются typedef:

Есть ещё один момент: ошибка не выдаётся, но и переопределения никакого не происходит.
Пример:

Как бы там ни было, используя в typedef "безымянные" структуры, можно убрать обёртки вокруг ffi.cdef.
(Только для typedef, но для winapi этого в большинстве случаев кажется достаточно.)

Update
Имена типов структур используются в сообщениях об ошибках,

Code: Select all

C:\APPs\Far3\Profile\Macros\scripts\sample.lua:31: cannot convert 'number' to 'struct 2785'
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

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

Post by fml2 »

Я тут в одном макро, написанном на Lua использованием ffi, увидел следующее:

В объявлении функции с суффиксом "W" (ReadConsoleOutputCharacterW) для строкового параметра используется "макровская" запись с T: LP[u]T[/u]STR lpCharacter. Кроме того, далее в тексте используется тип wchar_t.

Вопрос: надежно ли использование "Т" в объявлении? Т.е. можно ли полагаться на то, что FFI будет все "компилировать" так, как будто используется уникод? Или лучше писать "LPWSTR"?
User avatar
zg
zero-gravity
Posts: 6015
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 185 times
Contact:

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

Post by zg »

ffi понимает только базовые типы. LPTSTR — точно в их число не входит. значит он где-то определён. можно ли на это полагаться? не знаю. я лично не полагаюсь и все типы привожу к базовым.
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

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

Post by fml2 »

Ага! Вот оно откуда берется! А я удивлялся, откуда FFI знает все эти LPSTR и DWORD. Включение туда также и имен с T считаю разумным, т.к. это позволяет копировать объявления функций прямо со страничек MSDN. Может, еще следующее включить (если это возможно):

- WINAPI
- _In_, _In_opt_, _Inout_ и т.д.
- LPSECURITY_ATTRIBUTES
- LPOVERLAPPED

Тогда бы можно было копировать все определения прямо со страничек MSDN без каких-либо правок.

И еще какую-нибудь функцию для простого преобразования строк Lua в строки/объекты, пригодные для вызовов WINAPI, и обратно. А то я смотрю, тут даже "киты" кустарничают.
Post Reply

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