Страницы

Поиск по вопросам

среда, 19 июня 2019 г.

Как получить то, что было задано с define в lua FFI?

Многие функции системного программирования в linux работают с флагами (например, O_NONBLOCK). Но эти флаги же надо ещё и получить! Насколько я понимаю, флаги в заголовочных файлах определены при помощи #define. Традиционное нечто вроде ffi.C.O_NONBLOCK выдаёт ошибку, это не функция и не глобальная переменная! При этом файл заголовков подгружен при помощи библиотеки lcpp. И как же получить эти самые define'ы?


Ответ

Надо использовать не ffi.C. а ffi.lcpp_defs..
Пример 1
Файл test1.lua:
local lcpp = require("lcpp") local ffi = require("ffi")
ffi.cdef([[ #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; } test_t; ]])
print("MAX_SIZE = " .. ffi.lcpp_defs.MAX_SIZE)
Результат работы:
MAX_SIZE = 100
Пример 2
Файл test2.lua:
local lcpp = require("lcpp") local ffi = require("ffi")
ffi.cdef("#include \"test.h\"")
print("FREQUENCY_MHZ = " .. ffi.lcpp_defs.FREQUENCY_MHZ) print("FREQUENCY_KHZ = " .. ffi.lcpp_defs.FREQUENCY_KHZ) print("_PACKED_ = " .. ffi.lcpp_defs._PACKED_)
Файл test.h:
#ifndef TEST_H #define TEST_H
#define FREQUENCY_MHZ 2 #define FREQUENCY_KHZ (FREQUENCY_MHZ * 1000)
#define _PACKED_ __attribute__((packed))
#endif // TEST_H
Результат работы:
FREQUENCY_MHZ = 2 FREQUENCY_KHZ = (FREQUENCY_MHZ * 1000) _PACKED_ = __attribute__((packed))
Всё в общем-то работает, но из второго примера видно, что полного препроцессинга define'ов не происходит. На самом деле тут всё не так плохо.
Пример 3
Файл test3.lua:
local ffi = require("ffi") local lcpp = require("lcpp")
local data, state = lcpp.compile([[ #define ROW_CNT 0x0F #define COL_CNT 0x0A #define DATA_CNT (ROW_CNT * COL_CNT) int data[DATA_CNT]; ]]) local data_type = ffi.typeof(data)
print("data = " .. data) print("ROW_CNT = " .. state.defines.ROW_CNT) print("COL_CNT = " .. state.defines.COL_CNT) print("DATA_CNT = " .. state.defines.DATA_CNT) print("typeof(data) = " .. tostring(data_type))
Результат работы:
data = int data[(15*10)]; ROW_CNT = 0x0F COL_CNT = 0x0A DATA_CNT = (ROW_CNT * COL_CNT) typeof(data) = ctype
Как видно из этого примера, размерность массива вычислена правильно (150 элементов).

Комментариев нет:

Отправить комментарий