Как привести строку в uint32 luajit ffi - PullRequest
0 голосов
/ 04 июля 2019

Учтите, что str - это двоичная строка, которая содержит целое число без знака 32 в позиции 13.

Я пробовал это:

local value = ffi.cast("uint32_t", ffi.new("char[4]", str:sub(13,16)))

Однако возвращаемые данные являются "cdata" типа unsigned int, и я не знаю, как получить фактическое значение (Int)

Ответы [ 2 ]

1 голос
/ 05 июля 2019

В целом я согласен с ответом Егора Скриптунова.Для более обобщенного подхода (и, возможно, излишнего перегиба в данном конкретном случае) можно использовать тип объединения

local ffi = require 'ffi'

local union_type = ffi.typeof [[
  union {
    char bytes[4];
    uint32_t integer;
  }
]]

local union = union_type { bytes = 'abcd' }

print(string.format('0x%x', union.integer))

, отметив, что вам нужно беспокоиться о порядке байтов здесь;Вы можете подтвердить порядковый номер вашей системы с помощью ffi.abi('le') или ffi.abi('be').Если вы получаете вашу строку откуда-то еще (например, по сети), ее порядковый номер, скорее всего, где-то задокументирован.

Предположим, что вы хотите интерпретировать строку из приведенного выше примера (abcd) как big endian;тогда вы можете сделать это

local union do
  if ffi.abi('le') then
    union = union_type { bytes = ('abcd'):reverse() }
  else
    union = union_type { bytes = 'abcd' }
  end
end

Если система имеет младший порядок, переверните строку.В противном случае оставьте все как есть.

1 голос
/ 04 июля 2019

Индексирование преобразует массив cdata в число Lua

local value = ffi.cast("uint32_t*", ffi.new("const char*", str:sub(13,16)))[0]
...