Page 14 of 14

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

Posted: Tue 21 May, 2013 20:20
by John Doe
FFI — одна из стандартных библиотек luajit.
Позволяет из Lua кода вызывать внешние C-функции и использовать структуры данных C.
В данной теме задаём вопросы по использованию FFI

Примеры готовых скриптов:

Предупреждение: viewtopic.php?p=147610#p147610

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

Posted: Sat 12 May, 2018 13:54
by John Doe

Latest post of the previous page:

2useven10 wrote:
Sat 12 May, 2018 13:45
Если бы вы были более внимательны, то заметили бы, что пост правился 2 раза, и то что там есть сейчас работает.
Я следую логике обсуждения, ведь ниже вы нигде не сообщили о том, что исправили это.
Но да, сейчас код в порядке, и мало отличается от моего (отличие в том, что преобразование строки я убрал в функцию)

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

Posted: Sat 12 May, 2018 13:59
by 2useven10
John Doe wrote:
Sat 12 May, 2018 13:54
Я следую логике обсуждения, ведь ниже вы нигде не сообщили о том, что исправили это.
В посте, на который вы ссылаетесь, buniak_a_h, опечатку уже исправил о чём он собственно и пишет.

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

Posted: Sat 12 May, 2018 14:05
by John Doe
Вы правы, оказывается я руководствовался вашим первым ошибочным вариантом, и проглядел, что позже код был исправлен.

И раз всё работает, то я перестал понимать из-за чего вообще скандал разгорелся..

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

Posted: Sat 12 May, 2018 14:27
by 2useven10
John Doe, А вот так править ваш предыдущий пост некорректно.
На него ссылается мой пост, а после вашей правки теряется смысл моей ссылки.

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

Posted: Sat 12 May, 2018 14:39
by buniak_a_h
Всем, принимавшим участие, спасибо.
Была попытка написать макрос, копирующий файл с использованием CopyFileExW (с отрисовкой "градусника" и возможностью прерывания). Это было похоже на танцы с бубнами, но в конце концов всё заработало. Непонятки остались, но я как-то умудрился их обойти.

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

Posted: Sat 12 May, 2018 16:02
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() для приведённой функции.

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

Posted: Sat 12 May, 2018 16:29
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)

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

Posted: Sat 12 May, 2018 18:52
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 (*)()» и почему на строке из примера с сайта он может преобразовать, а на моём - нет?
Я не нашёл ответов. Если Вы знаете - ответьте, пожалуйста. Если нет - просто не отвечайте.

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

Posted: Sat 12 May, 2018 19:43
by buniak_a_h
Проблема решена заменой LARGE_INTEGER на LONGLONG. Непонятно, чем union-то провинился? Даже если я в нём оставляю одно LONGLONG-поле - всё равно не работает. Никаких ограничений в документации не нашёл - наоборот, там есть расширения (безымянные элементы)

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

Posted: Sun 13 May, 2018 07:31
by buniak_a_h
John Doe wrote:
Tue 21 May, 2013 20:20
Примеры готовых скриптов:
Возможно, Вас заинтересует (в качестве примера) скрипт CopyFileEx_Lua.lua - копирование файла вызовом функции CopyFileEx с определение CallBack-рутины. Там же (как иллюстрация) - арифметика с cdata-параметрами

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

Posted: Sun 13 May, 2018 15:07
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 (*)()» и почему на строке из примера с сайта он может преобразовать, а на моём - нет?
См. выше., но в таком случае сообщение об ошибке действительно странное и неинформативное.

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

Posted: Sun 13 May, 2018 19:30
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 бита, а как их интерпретировать - дело функции.