Вопросы по использованию FFI
- John Doe
- Бюрократ
- Posts: 13851
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 428 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
- Smitis
- Posts: 1709
- Joined: Fri 18 Mar, 2005 12:51
- Location: Питер
- Has thanked: 23 times
- Been thanked: 55 times
Вопросы по использованию FFI
Latest post of the previous page:
В подавляющем большинстве случаев достаточно убрать имя структуры
Code: Select all
ffi.cdef [[
typedef struct { // _CONSOLE_SELECTION_INFO
DWORD dwFlags;
COORD dwSelectionAnchor;
SMALL_RECT srSelection;
} CONSOLE_SELECTION_INFO, *PCONSOLE_SELECTION_INFO;
]]
Разум когда-нибудь победит.
- John Doe
- Бюрократ
- Posts: 13851
- Joined: Wed 27 Apr, 2005 20:42
- Has thanked: 73 times
- Been thanked: 428 times
- Contact:
Вопросы по использованию FFI
Да, выше по теме было.
Но имя структуры используется в сообщениях об ошибках, поэтому я бы не стал его комментировать, safe_def предпочтительнее.
На самом деле любая попытка переопределения это действительно ошибка, и даже странно что её нет с безымянными структурами и функциями.
В идеале было бы, если бы повторное определение проверялось на соответствие с имеющимся, и ошибка выдавалась бы в случае несовместимых определений.
Но нет, повторные просто проглатываются, не выдавая ошибок, но и не переопределяя.
- buniak_a_h
- Posts: 4262
- Joined: Sat 20 Apr, 2013 00:17
- Location: Санкт-Петробад
- Has thanked: 222 times
- Been thanked: 644 times
- Contact:
Вопросы по использованию FFI
Написал микроскрипт:
Code: Select all
local winapi=require"winapi"
local ffi = require("ffi")
far.Show('qq')
Code: Select all
╔════════════════════════════════════════════════════ LuaMacro ═════════════════════════════════════════════════════╗
║ ...ta\Roaming\Far Manager\Profile\Macros\modules\winapi.lua:319: attempt to redefine '_UNICODE_STRING' at line 52 ║
║ stack traceback: ║
║ [C]: in function 'require' ║
║ \\?\D:\ttt\www.lua:1: in main chunk ║
╟───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╢
║ { OK } ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- buniak_a_h
- Posts: 4262
- Joined: Sat 20 Apr, 2013 00:17
- Location: Санкт-Петробад
- Has thanked: 222 times
- Been thanked: 644 times
- Contact:
Вопросы по использованию FFI
Господа! Помогите, кто может!
Есть маленький скрипт: Описывается интерфейс к двум функциям из WINAPI: MessageBoxA и CopyFileA. У обеих функций есть параметры типа LPCTSTR (строка в кодировке ASCII).
Вызов MessageBoxA проходит ожидаемо (выводятся обе строки - в заголовке и на форм) А вот при вызове CopyFileA почему-то возникает ошибка:
При том, что параметры описаны абсолютно одинаково, аргумент-строка передается одна и та же...
Что я делаю не так? И как надо? Уже голову сломал...
Есть маленький скрипт: Описывается интерфейс к двум функциям из WINAPI: MessageBoxA и CopyFileA. У обеих функций есть параметры типа LPCTSTR (строка в кодировке ASCII).
Вызов MessageBoxA проходит ожидаемо (выводятся обе строки - в заголовке и на форм) А вот при вызове CopyFileA почему-то возникает ошибка:
bad argument #1 to '?' (cannot convert 'string' to 'const unsigned short *')
При том, что параметры описаны абсолютно одинаково, аргумент-строка передается одна и та же...
Что я делаю не так? И как надо? Уже голову сломал...
Вопросы по использованию FFI
Если вы используете неюникодные ф-и (почему?), то описывайте строковые аргументы как LPCSTR.
LPCTSTR - условный тип, который в зависимости от дефайнов считается либо LPCSTR, либо в LPCWSTR.
Видимо дефайны у вас и у ffi разные.
LPCTSTR - условный тип, который в зависимости от дефайнов считается либо LPCSTR, либо в LPCWSTR.
Видимо дефайны у вас и у ffi разные.
Вопросы по использованию FFI
Лучше пользоваться юникодными вариантами ф-й -- MessgeBoxW, CopyFileW и соответственно LPCWSTR.
Лишнее преобразование из юникода при этом надо выкинуть.
Юникодные строки должны закачиваться юникодным нулём. Lua сам такого не делает, поэтому
приходится в конце строки явно добавлять свой ноль -- "filename\0".
Лишнее преобразование из юникода при этом надо выкинуть.
Юникодные строки должны закачиваться юникодным нулём. Lua сам такого не делает, поэтому
приходится в конце строки явно добавлять свой ноль -- "filename\0".
-
- Posts: 6834
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 530 times
Вопросы по использованию FFI
Аналогичный вопрос уже задавался в данной ветке.
Ответ:
pcall(require,"winapi")
Надо в определениях заменить LPCTSTR на const char*
И как верно заметили выше, желательно работать с юникодными версиями функций Windows API. Зачем возвращаться к давно преодолённым ограничениям ASCII.
Last edited by Shmuel on Fri 11 May, 2018 06:58, edited 1 time in total.
Вопросы по использованию FFI
у меня работает. (немного поправил)
Last edited by 2useven10 on Fri 11 May, 2018 12:19, edited 2 times in total.
- buniak_a_h
- Posts: 4262
- Joined: Sat 20 Apr, 2013 00:17
- Location: Санкт-Петробад
- Has thanked: 222 times
- Been thanked: 644 times
- Contact:
Вопросы по использованию FFI
Это - первое, что я попробовал . Это - не помогает...Shmuel wrote: ↑Fri 11 May, 2018 06:54Аналогичный вопрос уже задавался в данной ветке.
Ответ:pcall(require,"winapi")
Это если б мне надо было, чтоб заработало. Но Вы пишете, что require"winapi" нужно для получения диагностики. «Ошибка сразу и вылезла». Вот она и вылезла, при том, что своих определений я не давал...
Впрочем, вопрос академический. У кого-то ошибка... Я просто убрал require"winapi".Надо в определениях заменить LPCTSTR на const char*
Пример с MessageBoxA взят из FFI Library. Просто я ничего не понимаю в кодировках, сделал как попугай, по образу и подобию примера. А там почему-то "A"-вариант.
- buniak_a_h
- Posts: 4262
- Joined: Sat 20 Apr, 2013 00:17
- Location: Санкт-Петробад
- Has thanked: 222 times
- Been thanked: 644 times
- Contact:
Вопросы по использованию FFI
У меня - нет. Т.е. ошибки не выдаёт, но и файл не копирует. Просто уничтожает. Может, дело в том, что \0 добавлен в inPath, а outPath получен дописыванием к InPath ещё чего-то (за финальным нулём!)?
- buniak_a_h
- Posts: 4262
- Joined: Sat 20 Apr, 2013 00:17
- Location: Санкт-Петробад
- Has thanked: 222 times
- Been thanked: 644 times
- Contact:
Вопросы по использованию FFI
Добавочка.
Если из inPath сначала убрать .. '\0', а затем отдельной строкой написать
inPath = inPath .. '\0'
то вылет следующий:
Code: Select all
╔══════════════════════════ Exception occurred ══════════════════════════╗
║ Exception: 0xC0000005 - EXCEPTION_ACCESS_VIOLATION ║
║ Details: Memory at FFFFFFFFFFFFFFFE could not be read ║
║ Address: 0x7FFCE9EE5F0F - KERNELBASE.dll!BasepCopyFileCallback ║
║ Source: ║
║ Function: OpenW ║
║ Module: :\Program Files\Far Manager\Plugins\LuaMacro\LuaMacro.dll ║
╟────────────────────────────────────────────────────────────────────────╢
║ { Unload plugin } [ Stack ] [ Minidump ] [ Ignore ] ║
╚════════════════════════════════════════════════════════════════════════╝
- buniak_a_h
- Posts: 4262
- Joined: Sat 20 Apr, 2013 00:17
- Location: Санкт-Петробад
- Has thanked: 222 times
- Been thanked: 644 times
- Contact:
Вопросы по использованию FFI
Если б Вы ещё написали, что такое ffi.cast (ну или хотя бы где про него прочитать)... А то повторяю как попугай...
-
- Posts: 6834
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 530 times
Вопросы по использованию FFI
Ну есть же сайт luajit, там вся документация по FFI.buniak_a_h wrote: ↑Fri 11 May, 2018 09:04 Если б Вы ещё написали, что такое ffi.cast (ну или хотя бы где про него прочитать
- buniak_a_h
- Posts: 4262
- Joined: Sat 20 Apr, 2013 00:17
- Location: Санкт-Петробад
- Has thanked: 222 times
- Been thanked: 644 times
- Contact:
Вопросы по использованию FFI
Ну вот как раз с этого сайта я и брал не-юникодный пример MessageBoxA. И, кстати, в этом примере ffi.cast НЕ БЫЛО! А работало прекрасно. Хотя именно в том примере я был уверен, что требуется преобразование типа - ведь раз интерпретатор работает с юникодными строками, то по логике и адрес должен указывать именно на юникодную строку... Но... Логика тут бессильна, просто надо запомнить...
Я догадался, что ffi.cast - это нечто типа приведения типа. Но как узнать, когда оно нужно, а когда - нет, этот сайт не разъясняет.
-
- Posts: 6834
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 530 times
Вопросы по использованию FFI
Документация по FFI (как и многие другие мануалы для программистов) предполагает определённый уровень подготовки читающего.buniak_a_h wrote: ↑Fri 11 May, 2018 09:26 Я догадался, что ffi.cast - это нечто типа приведения типа. Но как узнать, когда оно нужно, а когда - нет, этот сайт не разъясняет.
Как на мой взгляд, документация по FFI на сайте LuaJIT очень качественная.