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

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

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

Post by John Doe »

Latest post of the previous page:

Вы правы, оказывается я руководствовался вашим первым ошибочным вариантом, и проглядел, что позже код был исправлен.

И раз всё работает, то я перестал понимать из-за чего вообще скандал разгорелся..
2useven10
Posts: 5204
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 18 times
Been thanked: 310 times

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

Post by 2useven10 »

John Doe, А вот так править ваш предыдущий пост некорректно.
На него ссылается мой пост, а после вашей правки теряется смысл моей ссылки.
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

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

Post by buniak_a_h »

Всем, принимавшим участие, спасибо.
Была попытка написать макрос, копирующий файл с использованием CopyFileExW (с отрисовкой "градусника" и возможностью прерывания). Это было похоже на танцы с бубнами, но в конце концов всё заработало. Непонятки остались, но я как-то умудрился их обойти.
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

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

Post by buniak_a_h »

Всё же по поводу "танцев с бубнами".
Есть два скрипта, отличающихся ТОЛЬКО именем типа в ffi.cdef. В первом объявлен тип LPPROGRESS_ROUTINE (стандартное название для Call-Back-рутины в функции CopyFileEx, см. MSDN). Во втором класс LPPROGRESS_ROUTINE заменён на WWW.


Запуск первого скрипта приводит к ошибке:

Code: Select all

╔════════════════════════════════════════════ LuaMacro ════════════════════════════════════════════╗
║ \\?\C:\Temp\CopyFileEx\Out\qqq\qqq.Bad.lua:30: cannot convert 'function' to 'unsigned int (*)()' ║
║ stack traceback:                                                                                 ║
║    [C]: in function 'cast'                                                                       ║
║    \\?\C:\Temp\CopyFileEx\Out\qqq\qqq.Bad.lua:30: in main chunk                                  ║
╟──────────────────────────────────────────────────────────────────────────────────────────────────╢
║                                              { OK }                                              ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════╝
Причем, из скрипта можно даже выбросить описание LPPROGRESS_ROUTINE (из ffi.cdef) - ошибка останется той же. Второй работает нормально. Такое впечатление, что тип LPPROGRESS_ROUTINE где-то описан, причём неправильно. Другой вариант - в каком-то скрипте (не моём) вызывается аналогичная процедура, и не вызывается метод :free() для приведённой функции.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

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

Post by John Doe »

buniak_a_h wrote: Sat 12 May, 2018 16:02 Запуск первого скрипта приводит к ошибке:
Запуск обоих приводит к этой ошибке.

Перегрузите фар, и перепроверьте.
buniak_a_h wrote: Sat 12 May, 2018 16:02 Причем, из скрипта можно даже выбросить описание LPPROGRESS_ROUTINE
Это вряд ли.
Следует иметь ввиду, что определения работают глобально, а не для каждого скрипта, т.е. при их изменении необходимо перегрузить фар (или luamacro)
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

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

Post by buniak_a_h »

John Doe wrote: Sat 12 May, 2018 16:29 Перегрузите фар, и перепроверьте.
1. Перегружал не только фар, но и весь комп. А перед тем - и давал команду far.exe /clearcache, и удалял ВЕСЬ !!! каталог %FARLOCALPROFILE% - ничего не помогало.
2. У меня пока второй работает. Ну, т.е. не вылетает (так-то он ничего не делает). Есть и процедура копирования - она тоже работает. Пока. Вчера работала часа два, потом перестала. И восстановить работоспособность я (а)первый раз смог, по строчке добавляя к примеру с сайта FFI (второй пример из статьи Callback resource handling). (б) в какой-то момент и так восстановить работоспособность скрипта не смог, хотя ошибки в нём я не вижу. (в) Работоспособность восстановилась САМА (что неприятно).
Может, всё ломается при запуске второй-третьей и т.д. копии ФАРа?
3. Про "глобальные" определения я знал. И тут у меня возникла мысль: если при восстановлении я сначала определил WWW как в примере с сайта:
typedef int (__stdcall *WWW)(void *hwnd, intptr_t l);
и с тех пор ФАР не перезагружал, а второй скрипт работает, то получается, что "подробности" (DWORD вместо int - это ладно, а вот количество параметров - жесть!) не имеют значения для ffi.cast ? Там осталось такое описание (с двумя параметрами), а функция на самом деле получает все параметры...
4. И последнее. В чём ошибка-то? Что значит «cannot convert 'function' to 'unsigned int (*)()» и почему на строке из примера с сайта он может преобразовать, а на моём - нет?
Я не нашёл ответов. Если Вы знаете - ответьте, пожалуйста. Если нет - просто не отвечайте.
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

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

Post by buniak_a_h »

Проблема решена заменой LARGE_INTEGER на LONGLONG. Непонятно, чем union-то провинился? Даже если я в нём оставляю одно LONGLONG-поле - всё равно не работает. Никаких ограничений в документации не нашёл - наоборот, там есть расширения (безымянные элементы)
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

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

Post by buniak_a_h »

John Doe wrote: Tue 21 May, 2013 20:20 Примеры готовых скриптов:
Возможно, Вас заинтересует (в качестве примера) скрипт CopyFileEx_Lua.lua - копирование файла вызовом функции CopyFileEx с определение CallBack-рутины. Там же (как иллюстрация) - арифметика с cdata-параметрами
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

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

Post by John Doe »

buniak_a_h wrote: Sat 12 May, 2018 18:52 Может, всё ломается при запуске второй-третьей и т.д. копии ФАРа?
Нет.
buniak_a_h wrote: Sat 12 May, 2018 18:52 получается, что "подробности" (DWORD вместо int - это ладно, а вот количество параметров - жесть!) не имеют значения для ffi.cast ?

Code: Select all

There are no restrictions for the kind of Lua functions that can be called from the callback — no checks for the proper number of arguments are made. The return value of the Lua function will be converted to the result type and an error will be thrown for invalid conversions.
buniak_a_h wrote: Sat 12 May, 2018 19:43 Проблема решена заменой LARGE_INTEGER на LONGLONG. Непонятно, чем union-то провинился?

Code: Select all

Currently only certain C function types can be used as callback functions. Neither C vararg functions nor functions with [u]pass-by-value aggregate argument[/u] or result types are supported.
buniak_a_h wrote: Sat 12 May, 2018 18:52 В чём ошибка-то? Что значит «cannot convert 'function' to 'unsigned int (*)()» и почему на строке из примера с сайта он может преобразовать, а на моём - нет?
См. выше., но в таком случае сообщение об ошибке действительно странное и неинформативное.
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

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

Post by buniak_a_h »

John Doe wrote: Sun 13 May, 2018 15:07
buniak_a_h wrote: Sat 12 May, 2018 19:43 Проблема решена заменой LARGE_INTEGER на LONGLONG. Непонятно, чем union-то провинился?

Code: Select all

Currently only certain C function types can be used as callback functions. Neither C vararg functions nor functions with [u]pass-by-value aggregate argument[/u] or result types are supported.
Спасибо. Как-то не связался union с вариантом в одно поле с pass-by-value aggregate argument ... Решил, 64 бита - они и есть 64 бита, а как их интерпретировать - дело функции.
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

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

Post by citRiks »

Пытаюсь понять можно ли использовать в ФАРе с пользой многообещающий вот этот проект:
https://github.com/luapower/winapi/
https://luapower.com/winapi

в модулес создал папку winapi, скопировал туда содержимое гихаба, запускаю lua:=require'winapi'
Неизбежно получаю ашипку:

Винда 7 х64 Проф. Ед. СП1, ФАР х86 5577, х64 5596
Не критично, но хотелось бы разобраться,
прямое обращение к windows api было бы полезно иметь в распоряжении

PS
предупрреждение тут читал, 15 страниц тоже читал.
Запомнил или усвоил далеко не все конечно, и мало чего.
Если есть простое решение - спасибо,
если нет - прошу не ругаться сильно
viewtopic.php?p=147610#p147610

ИЗВИНЯЮСь, ЗАПУСТИЛ БЕЗ МАКРОСОВ, И КАЖЕТСЯ ЧТО ЭТО РЕШИЛО ПРОБЛЕМУ
Падает изза зависимости в glue, еще не разобрался до конца, но кажется что будет Ок,
если навести порядок с декларациями FFI
Last edited by citRiks on Sat 09 May, 2020 16:24, edited 4 times in total.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

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

Post by John Doe »

citRiks wrote: Sat 09 May, 2020 16:08 Пытаюсь понять можно ли использовать в ФАРе с пользой многообещающий вот этот проект:
Вам рано это пытаться, не прочитав тему, и не попытавшись самостоятельно использовать ffi.
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 »

John Doe wrote: Tue 12 May, 2020 10:58 Вам рано это пытаться, не прочитав тему, и не попытавшись самостоятельно использовать ffi.
вы очень правы,
но психологически трудно сделать себе двухдневный курс,
а нужно где-то именно столько времени на действительное вникание в тему.
Психологически проще тыкаться туда сюда в надежде "а может и так прокатит",
и потом выяснять почему не прокатило.
Да, так скорее всего в итоге возьмет не меньше тех же двух дней,
но мотивационно как-то проще
В этом же данном случае - вполне прокатило, починки оказались тривиальными
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

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

Post by John Doe »

citRiks wrote: Sun 31 May, 2020 09:08 двухдневный курс,
Вы оптимистичны.
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 »

John Doe wrote: Sun 31 May, 2020 09:19
citRiks wrote: Sun 31 May, 2020 09:08 двухдневный курс,
Вы оптимистичны.
если модуль готовый, хороший, то даже если он написан с ФФИ,
то его можно использовать искаропки даже лохам вроде меня )
Переопределение типов - это засада, но решилась на раз, -
первым делом загрузить этот модуль,
а затем для дальнейших определений использовать ФФИ из этого же модуля.
излагаю сумбурно, смысл сказанного лишь в том что не так страшен черт как его малютки
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 21 Jan, 2021 08:40
citRiks wrote: Thu 21 Jan, 2021 01:07 а я сейчас тестирую без макросов, вроде есть успехи
С этого надо было начинать.
Очень может быть что (в разных скриптах) у вас присутствуют два отличающихся определения ffi.
Это проглатывается молча, но срабатывает только первое.
John Doe,
ну да, мой косяк, бесполезные время и эксперименты
хоть опыта с ФФИ стало больше, но этот "опыт ради опыта" опять ..
Проблема была в том была в том что я все иницилаизации-декларации ФФИ перенес (не меняя) из _macroinit.lua в LuaFar_init.lua.
т.е., в скрипт макроса все попадаем уже после этих деклараций, все равно, в обоих вариантах как с макроинит так и луафар_инит.
Все еще непонятно почему ои что это меняет, но как-то так.
В свое оправдание:
1.) Из прошлого опыта ФФИ на переопределения ругался сразу, (впрочем сейчас не уверен что помню)
поэтому я не думал что с этим связано
2.) Был сооблазн решить заменой на char[?], это получилось результативно сразу и быстро, но вот далее ..
3.) не было изменений кода используемого кода ФФИ в последние месяцы
Last edited by citRiks on Thu 21 Jan, 2021 12:16, edited 1 time in total.
Post Reply

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