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

Столкнулись с проблемой в использовании макросов? Здесь можно получить помощь.
2useven10
Posts: 3010
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 2 times
Been thanked: 82 times

Получение привилегий backup/restore

Post by 2useven10 » Fri 08 Sep, 2017 20:23

Latest post of the previous page:

Shmuel wrote:
Fri 08 Sep, 2017 20:09
Любой стринг в Lua имеет дополнительный \0 в конце (в мануале отмечено).
Отлично. Правку откатил.

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

Получение привилегий backup/restore

Post by John Doe » Fri 08 Sep, 2017 20:24

Shmuel wrote:
Fri 08 Sep, 2017 20:09
Любой стринг в Lua имеет дополнительный \0 в конце (в мануале отмечено).
Действительно: https://www.lua.org/manual/5.1/manual.h ... _tolstring

Shmuel
Posts: 5202
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 16 times
Been thanked: 148 times

Получение привилегий backup/restore

Post by Shmuel » Fri 08 Sep, 2017 20:42

К сожалению, этого одного нуля недостаточно для стрингов в UTF-16. В своё время я предложил в форуме Lua, чтобы резервировалось место для двух нулей (\0\0), но предложение принято не было.

Smitis
Posts: 1470
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Получение привилегий backup/restore

Post by Smitis » Fri 08 Sep, 2017 20:51

Shmuel wrote:
Fri 08 Sep, 2017 20:42
К сожалению, этого одного нуля недостаточно для стрингов в UTF-16. В своё время я предложил в форуме Lua, чтобы резервировалось место для двух нулей (\0\0), но предложение принято не было.
Кстати, по поводу нуля. Обратил внимание, что в скриптах при вызове Utf8ToUtf16 добавляю "\0" к строке, на автомате, так сказать. Задумался - а разве Utf8ToUtf16 не должно конвертировать уже существующий "\0" в "\0\0"?
Разум когда-нибудь победит.

Shmuel
Posts: 5202
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 16 times
Been thanked: 148 times

Получение привилегий backup/restore

Post by Shmuel » Fri 08 Sep, 2017 20:57

Smitis wrote:
Fri 08 Sep, 2017 20:51
разве Utf8ToUtf16 не должно конвертировать уже существующий "\0" в "\0\0"?
Этот уже существующий \0 не является частью стринга - он лежит в его внутреннем представлении. Поэтому, если добавить в Utf8ToUtf16 к результату \0, мы нарушим корректность преобразования.

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

Получение привилегий backup/restore

Post by John Doe » Fri 08 Sep, 2017 20:59

Shmuel wrote:
Fri 08 Sep, 2017 20:42
К сожалению, этого одного нуля недостаточно для стрингов в UTF-16. В своё время я предложил в форуме Lua, чтобы резервировалось место для двух нулей (\0\0), но предложение принято не было.
Совсем памяти нет, уже ведь обсуждали viewtopic.php?p=111556#p111556, viewtopic.php?p=115201#p115201

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

Получение привилегий backup/restore

Post by John Doe » Fri 08 Sep, 2017 21:01

Shmuel wrote:
Fri 08 Sep, 2017 20:57
Этот уже существующий \0 не является частью стринга - он лежит в его внутреннем представлении. Поэтому, если добавить в Utf8ToUtf16 к результату \0, мы нарушим корректность преобразования.
По-моему вопрос о другом.

Code: Select all

Utf8ToUtf16(str.."\0")
Мне тоже казалось, что результат должен содержать в итоге два завершающих нуля, но сейчас усомнился (может получиться и ни одного, в зависимости от реализации).

Shmuel
Posts: 5202
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 16 times
Been thanked: 148 times

Получение привилегий backup/restore

Post by Shmuel » Fri 08 Sep, 2017 21:06

John Doe wrote:
Fri 08 Sep, 2017 21:01
Мне тоже казалось, что результат должен содержать в итоге два завершающих нуля
Вам правильно казалось. Результат будет содержать \0\0 в конце (и ещё один \0 внутренней репрезентации).

Smitis
Posts: 1470
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Получение привилегий backup/restore

Post by Smitis » Fri 08 Sep, 2017 21:36

Shmuel wrote:
Fri 08 Sep, 2017 20:57
Этот уже существующий \0 не является частью стринга - он лежит в его внутреннем представлении.
Кажется понял. Ноль есть в памяти, но он не считается частью строки, поэтому строковые функции, в том числе Utf8ToUtf16, его игнорируют. Что бы получить ноль в UTF-16 его надо ЯВНО добавить в строку. Можно добавить 0 в win.Utf8ToUtf16(str.."\0"), тогда в конце буфера будет ТРИ нулевых байта или win.Utf8ToUtf16(str).."\0", тогда будет ДВА нулевых байта, что в любом случае для работы юникодных функций достаточно.
Last edited by Smitis on Fri 08 Sep, 2017 21:56, edited 2 times in total.
Разум когда-нибудь победит.

User avatar
DrKnS
Posts: 4618
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 4 times
Been thanked: 121 times
Contact:

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

Post by DrKnS » Sat 09 Sep, 2017 09:23

Shmuel wrote:
Fri 08 Sep, 2017 20:57
Этот уже существующий \0 не является частью стринга - он лежит в его внутреннем представлении. Поэтому, если добавить в Utf8ToUtf16 к результату \0, мы нарушим корректность преобразования.
Так вроде бы \0 уже добавляется к новому внутреннему представлению?

Shmuel
Posts: 5202
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 16 times
Been thanked: 148 times

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

Post by Shmuel » Sat 09 Sep, 2017 10:37

DrKnS wrote:
Sat 09 Sep, 2017 09:23
Так вроде бы \0 уже добавляется к новому внутреннему представлению?
Это сделано для удобства внутренних операций LuaFAR. Там же двумя строчками ниже выставляется выходной размер, и он используется при формировании строки, выдаваемой "наружу". Другими словами, в функциях Lua-интерфейса этот \0 появляться не должен.

User avatar
DrKnS
Posts: 4618
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 4 times
Been thanked: 121 times
Contact:

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

Post by DrKnS » Sat 09 Sep, 2017 14:57

Shmuel wrote:
Sat 09 Sep, 2017 10:37
Другими словами, в функциях Lua-интерфейса этот \0 появляться не должен.
Да, действительно - по документации lua_pushlstring "makes (or reuses) an internal copy of the given string", теряя этот \0. Печально.

Shmuel
Posts: 5202
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 16 times
Been thanked: 148 times

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

Post by Shmuel » Sat 09 Sep, 2017 15:19

Печально, что главный автор Lua не согласился добавлять два "служебных" \0 вместо одного. (Причина, полагаю в том, что для него UTF-16 - экзотика, не стоящая внимания).

Добавить один (или сколько угодно) нулевых байтов к результату в LuaFAR совсем не проблема, но это будет некорректное преобразование.

Как вариант, можно было бы сделать дополнительные функции c Z ("zero") в конце имени, например Utf8ToUtf16Z.

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

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

Post by John Doe » Sat 09 Sep, 2017 15:47

К сожалению это мало чем отличается от того, чтобы добавить ноль конкатенацией с аргументом функции..

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

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

Post by John Doe » Tue 12 Sep, 2017 22:33

John Doe wrote:
Tue 25 Feb, 2014 12:56
Ещё вопрос.
В буфере из примера выше находится C-строка неизвестной длины.
Как лучше всего перевести её в lua-строку?
Очевидно надо использовать ffi.string, но поскольку длина заранее неизвестна, то возможны варианты
- объявить и использовать C.lstrlenW
- перевести в строку весь буфер, и использовать match"(.-)%z"
Давно было, и тогда мне почему то не пришло в голову решение на Lua, типа такого:

Code: Select all

local wchar = ffi.cast("wchar_t*",ptr)
local len = 0
while wchar[len]~=0 do len = len+1 end
Пример полностью:
Last edited by John Doe on Wed 13 Sep, 2017 18:00, edited 1 time in total.

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

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

Post by John Doe » Wed 13 Sep, 2017 17:28

Code: Select all

local ptr = ffi.new("char[?]",100,win.Utf8ToUtf16"test")
Похоже ffi.new тут работает не так, как я ожидал.
Из документации вроде бы следует, что ffi.new заполняет созданый массив нулями.
The elements of an array are initialized, starting at index zero. If a single initializer is given for an array, it's repeated for all remaining elements. This doesn't happen if two or more initializers are given: all remaining uninitialized elements are filled with zero bytes.
Однако в случае, когда в качестве инициализатора выступает строка, меньшая по длине, остаток видимо не обнуляется.
В документации этот частный случай не рассматривается, сказано только в общем:
Byte arrays may also be initialized with a Lua string. This copies the whole string plus a terminating zero-byte. The copy stops early only if the array has a known, fixed size.

Shmuel
Posts: 5202
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 16 times
Been thanked: 148 times

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

Post by Shmuel » Wed 13 Sep, 2017 17:36

John Doe wrote:
Wed 13 Sep, 2017 17:28
В документации этот частный случай не рассматривается, сказано только в общем
На мой взгляд, сказано исчерпывающе ("This copies the whole string plus a terminating zero-byte").

Post Reply

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