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

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

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

Post by John Doe »

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

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

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

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

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

Post by John Doe »

Latest post of the previous page:

Смотрю farapi.lua, и вижу что в определениях констант вместо специфических типов Far API используются стандартные.

Code: Select all

static const /*COLORDIALOGFLAGS*/ uint32_t
    CDF_NONE = 0;
Для чего это сделано?

Shmuel
Posts: 6029
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 26 times
Been thanked: 290 times

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

Post by Shmuel »

http://luajit.org/ext_ffi_semantics.html
static const declarations only work for integer types up to 32 bits.

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

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

Post by John Doe »

Это ограничение luajit FFI?
Вообще странно, я объявляю static const ULONG SEE_MASK_NO_CONSOLE = 0x00008000; и всё работает без ошибок.
Возможно всё в порядке, если константа фактически умещается в 32 бита.

Не туда смотрю, ULONG как раз 32 бита

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

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

Post by John Doe »

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

И в связи с этим у меня возник вопрос как правильно обращаться с константами-флагами?
Что происходит когда я передаю C-константы в функции bit.*? bit64.*?
Не происходит ли при этом лишних конвертаций из типов С в lua и обратно?

И нет ли таких конвертаций при обычном суммировании C-констант?

Shmuel
Posts: 6029
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 26 times
Been thanked: 290 times

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

Post by Shmuel »

John Doe wrote:Что происходит когда я передаю C-константы в функции bit.*? bit64.*?
Не происходит ли при этом лишних конвертаций из типов С в lua и обратно?

И нет ли таких конвертаций при обычном суммировании C-констант?
1. За bit.* не беспокойтесь, библиотека встроена в LuaJIT, всё компилируется. В LuaJIT 2.1 библиотека bit работает и с 64-битными данными. А функции bit64.* просто выдадут ошибку при подаче им на вход cdata.

2. Нет.

3. Нет.

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

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

Post by John Doe »

Спасибо.

Ещё один вопрос возник по следуещему абзацу документации:
http://luajit.org/ext_ffi_semantics.html#gc wrote:Similar rules apply for Lua strings which are implicitly converted to "const char *": the string object itself must be referenced somewhere or it'll be garbage collected eventually. The pointer will then point to stale data, which may have already been overwritten. Note that string literals are automatically kept alive as long as the function containing it (actually its prototype) is not garbage collected.
Я не понимаю как именно понимать последнее предложение.
Не могли бы вы привести пример такого использования?

Shmuel
Posts: 6029
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 26 times
Been thanked: 290 times

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

Post by Shmuel »

John Doe wrote:Я не понимаю как именно понимать последнее предложение.
Понимать так: использование стринговых литералов (то-есть: "foo", 'bar', [[baz]]) полностью безопасно, за исключением случаев, когда в другую ф-цию передаётся указатель на литерал, а ф-ция, содержащая этот литерал собирается сборщиком мусора.
  1. function f1()
  2.   return ffi.cast("const char*", "foo")
  3. end
  4.  
  5. local ptr = f1()
  6. f1 = nil
  7. -- после этого ф-ция f1 будет собрана сборщиком мусора
  8. -- использование ptr может быть чревато неприятностями

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

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

Post by John Doe »

Правильно ли я понял, что в первом предложении говорится о том, что опасен такой код :
  1. function f1()
  2.   local str = "foo"
  3.   local ptr = ffi.cast("const char*", str)
  4.   str = nil
  5.   f2(ptr)
  6. end
Но если используется не переменная, а литерал, то это нормально, пока "жива" функция f1:
  1. function f1()
  2.   local ptr = ffi.cast("const char*", "foo")
  3.   f2(ptr)
  4.   -- some other code
  5.   return
  6. end
Но что если вызов f2 - завершающая команда f1?
Это ведь получится tail call?
Как поведёт себя сборщик мусора?

Shmuel
Posts: 6029
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 26 times
Been thanked: 290 times

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

Post by Shmuel »

Оба примера абсолютно безопасны (даже не учитывая, что вы дважды определили local str в первой ф-ции, а это получаются две разных переменных).

Tail call, насколько я понимаю, не должен влиять на сборку мусора.

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

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

Post by John Doe »

Shmuel wrote:Оба примера абсолютно безопасны (даже не учитывая, что вы дважды определили local str в первой ф-ции, а это получаются две разных переменных).
Я не намеренно, уже исправил (убрал local)
Как я понимаю, это будет нарушением, поскольку the string object itself must be referenced somewhere or it'll be garbage collected eventually

Shmuel
Posts: 6029
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 26 times
Been thanked: 290 times

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

Post by Shmuel »

John Doe wrote:Как я понимаю, это будет нарушением, поскольку the string object itself must be referenced somewhere or it'll be garbage collected eventually
Сборщик мусора собирает объекты, а не переменные. ffi.cast("const char*", str) вернёт указатель на литерал, а не на переменную. Поскольку литерал собран сборщиком не будет, то ptr может быть использован безопасно.

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

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

Post by John Doe »

Сборщик мусора собирает объекты, а не переменные
Хм.
Я был уверерен что в данном случае объект-строка потеряв референс (str=nil) становится мусором и может быть собрана сборщиком.

Разве не это имеется ввиду в цитате the string object itself must be referenced somewhere or it'll be garbage collected eventually?

Shmuel
Posts: 6029
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 26 times
Been thanked: 290 times

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

Post by Shmuel »

Объект-строка здесь является литералом, а это особый случай. Он живёт, покуда ф-ция, его содержащая, жива. Даже если ссылок на него не осталось.

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

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

Post by John Doe »

Shmuel wrote:Объект-строка здесь является литералом
А в каких случаях lua-строка не является литералом?
local str = "foo" - это литерал
local str = tostring("foo") - это не литерал?
local str = far.LuafarVersion() - и это не литерал?

Shmuel
Posts: 6029
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 26 times
Been thanked: 290 times

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

Post by Shmuel »

Литерал здесь только "foo". Всё остальное - нет.

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

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

Post by John Doe »

Теперь я вижу что самый первый ваш ответ был вполне полон.
Спасибо за терпение ;-)

Post Reply

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