Доброго времени суток всем.
Встал вопрос преобразования массива из 8 байт, приходящего с устройства по сети CAN, в два дробных числа.
Кому интересно - подробности
Данные читаются через свою программу-сервер сети CAN (написана Qt5.5 в линуксе, x64), укладываются в БД PostgreSQL 9.5, для передачи в СКАДу. Нужно было переложить парсинг пакета на БД, чтобы разгрузить сервер. То, что на С++ решалось в одну строчку:
на plsql оказалось серьезной проблемой.
Единственное руководство помогло только в общих чертах - куда копать.
Проблема была - как получить массив байт в программе на С++: там нет типа bytea.
Методом научного тыка для 4-байтового bytea было найдено такое решение.
1. Написал программу на С:
2. Положил для компиляции файл в каталог /opt/PostgreSQL/9.5/include/postgresql/server/, чтобы не указывать в #include пути.
3. Скомпилировал по указанному руководству; для линукса это:
cc -fpic -c bytea_to_real.c
cc -shared -o bytea_to_real.so bytea_to_real.o
4. Скомпилированный файл bytea_to_real.so перенес в папку /opt/PostgreSQL/9.5/lib/bytea_to_real.so, где ему и место.
5. В БД PG создал функцию:
CREATEORREPLACEFUNCTION public.bytea_to_real(INDATA bytea) RETURNS real AS'/opt/PostgreSQL/9.5/lib/bytea_to_real.so','bytea_to_real'-- каталог окончательного размещения--'/opt/PostgreSQL/9.5/include/postgresql/server/bytea_to_real.so', 'bytea_to_real' -- каталог компиляции на время отладки--'bytea_to_real.so', 'bytea_to_real' -- не находит; видно, что-то с путямиLANGUAGE C STRICT;
6. Закрыл окно запроса, и открыл новое. Выполнил запрос:
SELECT
substring(log.can_value FROM 1 FOR 4)AS ss_1_4,
bytea_to_real(substring(log.can_value FROM 1 FOR 4))AS ba_f_1,
substring(log.can_value FROM 5 FOR 4)AS ss_5_4,
bytea_to_real(substring(log.can_value FROM 5 FOR 4))AS ba_f_2,
log.can_value
FROM can_log log
ORDERBY log.dt DESCLIMIT100;
И - все... Работает. "Приходи, кума, любоваться".
Дальше функцию привязал к триггеру trg_can_log_bi, где уже лежала функция для цифровых данных, но это уже детали. Работает и там.
Вот... хотел поделиться работающим вариантом. Когда искал примеры сам - не нашел; наверное, плохо искал...
Надеюсь, кому-то пригодится. Да еще в комментариях, может быть, и поправят, и улучшат те, кто знает С++ и PostgreSQL лучше меня.
Не судите строго.