Вопросы по использованию FFI
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Вопросы по использованию FFI
FFI — одна из стандартных библиотек luajit.
Позволяет из Lua кода вызывать внешние C-функции и использовать структуры данных C.
В данной теме задаём вопросы по использованию FFI
Заготовка для документации: viewtopic.php?f=57&t=8418&p=147610#p147610
Примеры готовых скриптов:
Предупреждение: viewtopic.php?p=147610#p147610
Позволяет из Lua кода вызывать внешние C-функции и использовать структуры данных C.
В данной теме задаём вопросы по использованию FFI
Заготовка для документации: viewtopic.php?f=57&t=8418&p=147610#p147610
Примеры готовых скриптов:
Предупреждение: viewtopic.php?p=147610#p147610
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Re: Вопросы по использованию FFI
Latest post of the previous page:
Предвижу сложности. Возьмём такой сценарий.Shmuel wrote:Можно было бы при этом сделать и модуль winapiex (т.е. "extended").
1) Какой-то скрипт не использует модуль winapiex.lua, но для своих нужд определяет тип "TOKEN_PRIVILEGES"
2) Другой скрипт пытается после этого загрузить winapiex.lua, но обламывается, т.к. ffi не даёт переопределить.
И pcall в данном случае не особо поможет
P.S.
Насколько я могу судить, облом только при попытке переопределить структуры.
-
- Posts: 6819
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 528 times
Re: Вопросы по использованию FFI
Либо определения оба корректны, тогда проблем нет, либо (в крайне редких случаях) можно переименовать имя структуры.John Doe wrote:Хотя... Предвижу сложности. Возьмём такой сценарий.
......
Если быть последовательными, то кроме двух вышеупомянутых файлов модулями нужно сделать и panelsort.lua, и moonscript.lua. Их все можно поместить в папку LuaMacro\modules, а плагин будет добавлять эту папку в package.path.
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Re: Вопросы по использованию FFI
Проблема не в этом.Либо определения оба корректны, тогда проблем нет, либо (в крайне редких случаях) можно переименовать имя структуры.
Любое единичное переопределение можно завернуть в pcall, как мы и делаем сейчас.
Модуль же содержит множество определений, его в pcall не завернёшь.
Устранение конфликтов переименованием структур - это какая-то ерунда, т.к. во-первых от имён структур могут зависить другие определения.
И во-вторых, конфликт в своём скрипте я устраню как-нибудь. Но если я скачал скрипт с форума, то ковырять его как-то вообще нехорошо.
-
- Posts: 6819
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 528 times
Re: Вопросы по использованию FFI
Внутри модуля вполне можно использовать pcall, многократно.John Doe wrote:Любое единичное переопределение можно завернуть в pcall, как мы и делаем сейчас.
Модуль же содержит множество определений, его в pcall не завернёшь.
Если кто-то выложит для скачивания модуль или скрипт, несовместимый со стандартной поставкой Фара, это его проблемы.
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Re: Вопросы по использованию FFI
Не всё так просто.Shmuel wrote:Если кто-то выложит для скачивания модуль или скрипт, несовместимый со стандартной поставкой Фара, это его проблемы.
Скрипт будет совместим со стандартной поставкой.
И даже с другими скриптами, использующими модуль, если они выполняются ДО него.
Можно, но при большом количестве структур - это будет громоздко и медленно.Shmuel wrote:Внутри модуля вполне можно использовать pcall, многократно.
Любую проблему можно решить, я понимаю. Но зачем создавать её искуственно?
-
- Posts: 6819
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 528 times
Re: Вопросы по использованию FFI
Если скрипт определяет те же структуры, что есть в стандартной поставке, то он несовместим, вот и всё.John Doe wrote:Не всё так просто.
Скрипт будет совместим со стандартной поставкой.
И даже с другими скриптами, использующими модуль, если они выполняются ДО него.
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Re: Вопросы по использованию FFI
Сегодня совместим, а завтра мы добавили в поставку новые структуры, и стал несовместим. Нехорошо.
-
- Posts: 6819
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 528 times
Re: Вопросы по использованию FFI
Это не проблема, если сторонние скрипты будут вызывать require "winapi" перед своими ffi-определениями. Ошибка сразу и вылезет.John Doe wrote:Сегодня совместим, а завтра мы добавили в поставку новые структуры, и стал несовместим. Нехорошо.
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Re: Вопросы по использованию FFI
Не вылезет, ведь свои определения завёрнуты в pcall.
Но да, если обязать всех делать require ("winapi") до собственных деклараций, то это поможет решить проблему. Административно.
Но да, если обязать всех делать require ("winapi") до собственных деклараций, то это поможет решить проблему. Административно.
-
- Posts: 6819
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 528 times
Re: Вопросы по использованию FFI
Ситуация на данный момент мало чем отличается от всего, что вы описываете.
-- Два разных скрипта могут определить конфликтующие декларации.
-- Скрипт может завернуть свою конфликтующую с фаровской декларацию в pcall, и это пройдёт незамеченным.
-- "Административно" - никто не запрещает пользоваться исключительно глобальными переменными с короткими именами, никто не запрещает сделать _G.far=45 и т.д.
-- Два разных скрипта могут определить конфликтующие декларации.
-- Скрипт может завернуть свою конфликтующую с фаровской декларацию в pcall, и это пройдёт незамеченным.
-- "Административно" - никто не запрещает пользоваться исключительно глобальными переменными с короткими именами, никто не запрещает сделать _G.far=45 и т.д.
Last edited by Shmuel on Thu 19 Jun, 2014 20:37, edited 1 time in total.
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Re: Вопросы по использованию FFI
Это у нас уже принято решать обёртками вокруг ffi.cdef.Shmuel wrote:-- Два разных скрипта могут определить конфликтующие декларации.
Реальная проблема будет только если декларации окажутся несовместимыми. Это возможно, но сравнительно маловероятно.
Это вообще крайне маловероятно, в фаре только winapi/farapi, и пользовательская декларация может оказаться несовместимой разве что в результате ошибки пользователя.Shmuel wrote:-- Скрипт может завернуть свою конфликтующую с фаровской декларацию в pcall, и это пройдёт незамеченным.
Предлагаю рассмотреть поимённо.Shmuel wrote:И т.д. и т.п.
На данный момент фаровские определения грузятся первыми.Shmuel wrote:Ситуация на данный момент мало чем отличается от всего, что вы описываете.
Из этого следует, что в случае конфликта пострадает только сам конфликтующий скрипт.
Если же фаровские определения станут модулями, то в случае конфликта наоборот, пострадают все прочие скрипты, честно использующие require в начале.
Причём сообщение об ошибке вообще не будет указывать на реальный источник конфликта.
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Re: Вопросы по использованию FFI
Вот ещё информация к размышлению:
ffi.cdef выдаёт ошибку в случае попытки повторного объявления структуры с тем же именем типа.
Но если объявить структуру с другим именем типа (struct NewName {...}), или без имени (struct {...}), то никаких сообщений об ошибке не будет.
Может быть это стоит использовать? Ведь по факту в winapi не используются имена типов структур, а типы определяются typedef:
Есть ещё один момент: ошибка не выдаётся, но и переопределения никакого не происходит.
Пример:
Как бы там ни было, используя в typedef "безымянные" структуры, можно убрать обёртки вокруг ffi.cdef.
(Только для typedef, но для winapi этого в большинстве случаев кажется достаточно.)
Update
Имена типов структур используются в сообщениях об ошибках,
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'
Вопросы по использованию FFI
Я тут в одном макро, написанном на Lua использованием ffi, увидел следующее:
В объявлении функции с суффиксом "W" (
Вопрос: надежно ли использование "Т" в объявлении? Т.е. можно ли полагаться на то, что FFI будет все "компилировать" так, как будто используется уникод? Или лучше писать "LPWSTR"?
В объявлении функции с суффиксом "W" (
ReadConsoleOutputCharacterW
) для строкового параметра используется "макровская" запись с T: LP[u]T[/u]STR lpCharacter
. Кроме того, далее в тексте используется тип wchar_t
.Вопрос: надежно ли использование "Т" в объявлении? Т.е. можно ли полагаться на то, что FFI будет все "компилировать" так, как будто используется уникод? Или лучше писать "LPWSTR"?
- zg
- zero-gravity
- Posts: 6016
- Joined: Tue 15 Mar, 2005 17:36
- Location: riga
- Been thanked: 185 times
- Contact:
Вопросы по использованию FFI
ffi понимает только базовые типы. LPTSTR — точно в их число не входит. значит он где-то определён. можно ли на это полагаться? не знаю. я лично не полагаюсь и все типы привожу к базовым.
Вопросы по использованию FFI
Ага! Вот оно откуда берется! А я удивлялся, откуда FFI знает все эти LPSTR и DWORD. Включение туда также и имен с T считаю разумным, т.к. это позволяет копировать объявления функций прямо со страничек MSDN. Может, еще следующее включить (если это возможно):
- WINAPI
- _In_, _In_opt_, _Inout_ и т.д.
- LPSECURITY_ATTRIBUTES
- LPOVERLAPPED
Тогда бы можно было копировать все определения прямо со страничек MSDN без каких-либо правок.
И еще какую-нибудь функцию для простого преобразования строк Lua в строки/объекты, пригодные для вызовов WINAPI, и обратно. А то я смотрю, тут даже "киты" кустарничают.
- WINAPI
- _In_, _In_opt_, _Inout_ и т.д.
- LPSECURITY_ATTRIBUTES
- LPOVERLAPPED
Тогда бы можно было копировать все определения прямо со страничек MSDN без каких-либо правок.
И еще какую-нибудь функцию для простого преобразования строк Lua в строки/объекты, пригодные для вызовов WINAPI, и обратно. А то я смотрю, тут даже "киты" кустарничают.