Вопросы по использованию 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
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 »

Latest post of the previous page:

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, и обратно. А то я смотрю, тут даже "киты" кустарничают.
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 »

- WINAPI
- _In_, _In_opt_, _Inout_ и т.д.
Невозможно, ffi макросы не понимает.
LPSECURITY_ATTRIBUTES
Да, в winapi.lua сейчас определяется SECURITY_ATTRIBUTES, вполне разумно добавить туда же и производные типы.
LPOVERLAPPED
А тут не уверен (так ведь можно добавлять бесконечно).
В настоящий момент в winapi.lua в основном представлены типы отсюда.
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

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

Post by fml2 »

John Doe wrote:А тут не уверен (так ведь можно добавлять бесконечно).
LPOVERLAPPED используется как параметр в функции ReadFile (и WriteFile). Думаю, что т.к. эти функции "довольно базовые" (или нет?), то хорошо было бы, чтобы типы их параметеров регистрировались автоматически. А насчет бесконечности -- это да, WINAPI большой...
Maximus5
Posts: 3295
Joined: Sun 11 Nov, 2007 02:03
Been thanked: 10 times
Contact:

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

Post by Maximus5 »

Что-то я сомневаюсь, что вы когда-нибудь реально на lua будете использовать LPOVERLAPPED )
IMHO его достаточно на "void*" заменить
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

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

Post by fml2 »

Реально я его и не собираюсь использовать. Но в объявлении функции (скопировано из MSDN) оно присутствует. Редактировать там что-либо не хочется. Так что в тексте это имя встречается.

Это "реальное" использование? Вроде нет. Но ведь и не воображаемое! :-)
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

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

Post by fml2 »

Как с помощью string.format вывести значение WINAPI HANDLE? Спецификатора %p в Lua вроде нету. При использовании %u в качестве формата и ffi.cast("unsigned int", handle) в качестве значения выдается ошибка: bad argument #2 to 'format' (number expected, got cdata).
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

fml2 wrote:Как с помощью string.format вывести значение WINAPI HANDLE? Спецификатора %p в Lua вроде нету.
В Lua нету, в LuaJIT есть.
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

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

Post by fml2 »

Я пробовал и с %p, но выводилось просто "%p", т.е. спецификатор ничего не преобразовывал, а выводился просто как строка. Что там используется (просто Lua или LuaJit), в чем между ними разница и как сказать, чем именно хочешь пользоваться, я не знаю.

По идее, любой Jit должен "влезать" сам по мере надобности/целесообразности. И не должен менять результат выполнения программы. Поэтому меня удивляет, что в одном месте %p есть, а в другом нет.

А как сделать без %p?
Post Reply

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