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

Столкнулись с проблемой в использовании макросов? Здесь можно получить помощь.
User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

FFI — одна из стандартных библиотек luajit.
Позволяет из Lua кода вызывать внешние C-функции и использовать структуры данных C.
В данной теме задаём вопросы по использованию FFI

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

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

Shmuel
Posts: 5976
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 25 times
Been thanked: 257 times

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

Post by Shmuel »

Latest post of the previous page:

John Doe wrote:Возможно ли через ffi как-то воспользоваться C-функциями far api?
Да, для этого даже добавлен файл LuaMacro\farapi.lua.
Для получения указателя на PluginStartupInfo есть ф-ция far.CPluginStartupInfo, нужно cделать ffi.cast() от результата её вызова.

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

Не могу сообразить как этим воспользоваться.
При попытке ffi.cast("PluginStartupInfo*",far.CPluginStartupInfo()) получаю ошибку declaration specifier expected near 'PluginStartupInfo'

Shmuel
Posts: 5976
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 25 times
Been thanked: 257 times

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

Post by Shmuel »

Попробуйте "struct PluginStartupInfo*".

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

Спасибо, так отлично.

Пытаясь углубиться далее понял что документация FFI слишком лаконична, хотя много информации можно выудить из рассылки.

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

Shmuel wrote:
John Doe wrote:Возможно ли через ffi как-то воспользоваться C-функциями far api?
Да, для этого даже добавлен файл LuaMacro\farapi.lua.
Также в комплекте есть winapi.lua, в связи с чем возникло несколько вопросов по использованию специфических типов данных winapi.
При определении C-функций нельзя просто так взять её описание на MSDN, нужно ещё заменить Windows-типы данных на стандартные, либо предварительно определить нужные типы.

Меня интересует какой из путей предпочтительнее?

(В winapi.lua определены слишком малая их часть)

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

Также интересует вопрос как лучше определять C-константы.
Например верно ли это:

Code: Select all

local STD_OUTPUT_HANDLE = ffi.new("unsigned long",-11)
local INVALID_HANDLE_VALUE = ffi.cast("void*",-1)

Shmuel
Posts: 5976
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 25 times
Been thanked: 257 times

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

Post by Shmuel »

John Doe wrote:При определении C-функций нельзя просто так взять её описание на MSDN, нужно ещё заменить Windows-типы данных на стандартные, либо предварительно определить нужные типы.

Меня интересует какой из путей предпочтительнее?

(В winapi.lua определены слишком малая их часть)
1. Оба пути равнозначны, предпочтительность того или иного зависит от разных факторов.
2. "Малая часть" - в основном то, что нужно для farapi.lua.
John Doe wrote:Также интересует вопрос как лучше определять C-константы.
Например верно ли это:

Code: Select all

local STD_OUTPUT_HANDLE = ffi.new("unsigned long",-11)
local INVALID_HANDLE_VALUE = ffi.cast("void*",-1)
Посмотрите в farapi.lua, там определена куча констант.
Пока есть проблема только с 64-битными константами, их действительно приходится определять вне ffi.cdef, но для этого не надо ffi.new, просто можно определить MY_CONST=123LL.

Для STD_OUTPUT_HANDLE можно
ffi.cdef "static const unsigned long STD_OUTPUT_HANDLE = -11;"

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

Shmuel wrote:Посмотрите в farapi.lua, там определена куча констант.
Поначалу я не понял как использовать определённые таким образом константы, но методом тыка получилось через индексацию ffi.C. Или можно иначе?
И как правильно проверить что константа уже была определена (чтобы избежать проблемы при попытке "переопределения" константы)?

Shmuel
Posts: 5976
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 25 times
Been thanked: 257 times

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

Post by Shmuel »

1. Нельзя иначе.
2. pcall(ffi.cdef, arg). Есть и другие способы, см. в коде макросов zg.

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

Shmuel wrote:2. pcall(ffi.cdef, arg). Есть и другие способы, см. в коде макросов zg.
В picture.lua используется safe_cdef
Для безопасного определения констант можно использовать нечто подобное:
  1. local function safe_const(typename,name,val)
  2.   if not pcall(function(const)return ffi.C[const] end,name) then
  3.     ffi.cdef(([[static const %s %s = %s;]]):format(typename,name,val))
  4.   end
  5. end
Использовать как safe_const("ULONG","SEE_MASK_NOCLOSEPROCESS","0x00000040")

P.S.
Всё-таки как же определить константу-указатель?
Вот это вызывает invalid C type

Shmuel
Posts: 5976
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 25 times
Been thanked: 257 times

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

Post by Shmuel »

John Doe wrote:Всё-таки как же определить константу-указатель?
Так, как сделано здесь (для INVALID_HANDLE_VALUE).

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

Shmuel wrote:
John Doe wrote:При определении C-функций нельзя просто так взять её описание на MSDN, нужно ещё заменить Windows-типы данных на стандартные, либо предварительно определить нужные типы.
1. Оба пути равнозначны, предпочтительность того или иного зависит от разных факторов.
Вообще кажется удобным использовать в определениях функций именно Windows data types.
Однако необходимость их дефиниции, плюс защита от редефиниции сильно снижают это удобство.

Раз уж у нас есть winapi.lua, может быть стоит определить там основные типы? http://msdn.microsoft.com/library/aa383751

Shmuel
Posts: 5976
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 25 times
Been thanked: 257 times

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

Post by Shmuel »

Делайте патч.

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

Попалось два варианта
https://github.com/luapower/winapi/blob ... ntypes.lua
https://github.com/Wiladams/LJIT2Win32/ ... WTypes.lua

Или просто код собранный в той статье MSDN
Хотя... в алфавитном порядке оно бесполезно, проще взять исходник (BaseTsd.h;WinDef.h;WinNT.h)

User avatar
John Doe
Бюрократ
Posts: 12604
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 35 times
Been thanked: 260 times

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

Post by John Doe »

В общем, чтобы сделать годный патч надо разбираться в C побольше чем я.
Так что оставляю на ваше усмотрение.

Shmuel
Posts: 5976
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 25 times
Been thanked: 257 times

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

Post by Shmuel »

John Doe wrote:Так что оставляю на ваше усмотрение.
Тут дело не в усмотрении, а во времени, которое не всегда есть.
Заводите тикет на мантисе, может у кого-нибудь когда-нибудь руки дойдут.

Post Reply

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