Вопросы по использованию 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
-
- Posts: 6820
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 528 times
Re: Вопросы по использованию FFI
Latest post of the previous page:
Это не проблема, если сторонние скрипты будут вызывать 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: 6820
- 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, и обратно. А то я смотрю, тут даже "киты" кустарничают.
- John Doe
- Бюрократ
- Posts: 13807
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 426 times
- Contact:
Вопросы по использованию FFI
Невозможно, ffi макросы не понимает.- WINAPI
- _In_, _In_opt_, _Inout_ и т.д.
Да, в winapi.lua сейчас определяется SECURITY_ATTRIBUTES, вполне разумно добавить туда же и производные типы.LPSECURITY_ATTRIBUTES
А тут не уверен (так ведь можно добавлять бесконечно).LPOVERLAPPED
В настоящий момент в winapi.lua в основном представлены типы отсюда.
Вопросы по использованию FFI
LPOVERLAPPED используется как параметр в функции ReadFile (и WriteFile). Думаю, что т.к. эти функции "довольно базовые" (или нет?), то хорошо было бы, чтобы типы их параметеров регистрировались автоматически. А насчет бесконечности -- это да, WINAPI большой...John Doe wrote:А тут не уверен (так ведь можно добавлять бесконечно).
Вопросы по использованию FFI
Что-то я сомневаюсь, что вы когда-нибудь реально на lua будете использовать LPOVERLAPPED )
IMHO его достаточно на "void*" заменить
IMHO его достаточно на "void*" заменить
Вопросы по использованию FFI
Реально я его и не собираюсь использовать. Но в объявлении функции (скопировано из MSDN) оно присутствует. Редактировать там что-либо не хочется. Так что в тексте это имя встречается.
Это "реальное" использование? Вроде нет. Но ведь и не воображаемое! :-)
Это "реальное" использование? Вроде нет. Но ведь и не воображаемое! :-)
Вопросы по использованию FFI
Как с помощью
string.format
вывести значение WINAPI HANDLE? Спецификатора %p
в Lua вроде нету. При использовании %u
в качестве формата и ffi.cast("unsigned int", handle)
в качестве значения выдается ошибка: bad argument #2 to 'format' (number expected, got cdata).Вопросы по использованию FFI
Я пробовал и с %p, но выводилось просто "%p", т.е. спецификатор ничего не преобразовывал, а выводился просто как строка. Что там используется (просто Lua или LuaJit), в чем между ними разница и как сказать, чем именно хочешь пользоваться, я не знаю.
По идее, любой Jit должен "влезать" сам по мере надобности/целесообразности. И не должен менять результат выполнения программы. Поэтому меня удивляет, что в одном месте %p есть, а в другом нет.
А как сделать без %p?
По идее, любой Jit должен "влезать" сам по мере надобности/целесообразности. И не должен менять результат выполнения программы. Поэтому меня удивляет, что в одном месте %p есть, а в другом нет.
А как сделать без %p?