
Прошла пора дипломов и я хочу поделиться своим рецептом его выполнения. Итак: тема сложная, времени мало, писать все «с нуля» или искать готовые библиотеки — нет большого желания, тем более что мне важна скорость работы системы, а от левых самописных библиотек можно ждать любого подвоха.
Надо сказать что размышлял я недолго и пришел к следующим выводам:
- Операционная система — тут думать особо не пришлось: т.к. я являюсь поклонником Debian (к слову: мое решение можно перенести и на Windows).
- Интерфейс будущей программы — C++, Qt.
- Логика программы — MatLab.
Подготовка
Для работы системы нам необходимы следующие компоненты:
- Так называемый MATLAB Compiler Runtime. Это свободно распространяемый набор динамических библиотек MatLab. Скачать его можно с официального сайта и пользовать на свое усмотрение.
- Собственно сам Qt. Скачивается из репозиториев Linux, либо с официального сайта.
Установка
MATLAB Compiler Runtime распространяется в zip архиве. Внутри вы найдете файл install.sh. После его запуска откроется графический инсталятор, который в 3 клика сделает свое дело.
Qt ставится из репозиториев. Если вы скачали свеженькую версию с сайта, то необходимо выполнить следующие действия:
Под рутом:
mkdir /opt/QtSDK chown %username% /opt/QtSDK
Дальнейшую установку производим обязательно от имени пользователя и в каталог /opt/QtSDK
С установкой закончили, переходим к настройкам:
Необходимо прописать библиотеки в системе, для этого:
echo /usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/runtime/glnxa64 >> /etc/ld.so.conf.d/matlabLibs.conf echo /usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/os/glnxa64 >> /etc/ld.so.conf.d/matlabLibs.conf echo /usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/java/jre/glnxa64/jre/lib/amd64/native_threads >> /etc/ld.so.conf.d/matlabLibs.conf echo /usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/java/jre/glnxa64/jre/lib/amd64/server >> /etc/ld.so.conf.d/matlabLibs.conf echo /usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/java/jre/glnxa64/jre/lib/amd64 >> /etc/ld.so.conf.d/matlabLibs.conf ldconfig
И прописать переменную окружения XAPPLRESDIR (необходимы права рута):
export XAPPLRESDIR="/usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/X11/app-defaults"
Далее необходимо скопировать файл: /usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/X11/app-defaults/Matlab в домашнюю директорию польз��вателя. Вообще, в теории, этого делать не надо, но без этого ничего не работает. Это известный баг, но его пока еще не исправили.
Пройдусь немного по путям к библиотекам:
- Часть /usr/local/MATLAB/MATLAB_Compiler_Runtime/ может меняться в зависимости от того, куда вы устанавливали MCR.
- Часть v716/ это версия самого MatLab и она тоже может меняться.
- Часть glnxa64/ для 64 битной ОС и glnxa32 для 32 битной ОС.
Да и вообще. Все эти пути будут написаны на финайльной стадии установки MCR, но копировать их я не советую и предлагаю перепроверить и переписать все вручную (не знаю в чем тут дело, но у меня на двух разных машинах тупое копирование этих путей не дало результатов). Также после установки будет еще один путь: /usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/os/glnxa64, его прописывать я не советую: т.к. после этого у меня отказались запускаться все программы, а без него все прекрасно работает.
Расчехляем MatLab
Теперь можно писать логику будущего приложения. Создаем новый m-файл и пишем новую функцию. Функция у нас будет простая: будем суммировать два переданных массива чисел:
function [out] = SUM(in1, in2) out = in1 + in2; end
Все готово для компиляции этой функции в динамическую библиотеку:
- Пишем в консоли MatLab: deploytool.
- В открывшемся окне пишем имя проекта, его расположение а из выпадающего списка выбираем C Shared library и нажимаем OK. Учтите, что в Linux названия библиотек начинается со слова lib, поэтому и проект стоит называть libsum.prj
- В окне Exported Functions нажимаем на Add files и добавляем только что созданную функцию.
- Нажимаем на кнопку Build и дожидаемся окончания компиляции.
После компиляции в папке с проектом окажется папка distrib, в которой и будет находиться наша библиотека и заголовочный файл.
На этом работа с MatLab закончена.
Расчехляем Qt
Запускаем Qt и создаем новый проект.
В pro файле прописываем пути к библиотекам и заголовочным файлам:
INCLUDEPATH += /usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/extern/include LIBS += -L/usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/bin/glnxa64/ -leng -lm #При условии, что скомпилированная библиотека лежит в каталоге lib создаваемого проекта LIBS += -L$$PWD/lib/ -lsum #При условии, что заголовочный файл лежит в каталоге include создаваемого проекта INCLUDEPATH += $$PWD/include DEPENDPATH += $$PWD/include
В самом проекте пишем следующией код:
#include <QtCore/QCoreApplication> #include <libsum.h> #include <iostream> using namespace std; int main(int argc, char *argv[]) { cout<<"Loading..."<<endl; if (!libsumInitializeWithHandlers(NULL, 0)){ cout<<"Could not initialize the application."<<endl; return -1; } if (!libsumInitialize()){ cout<<"Could not initialize the library."<<endl; return -2; } mxArray *in1 = mxCreateDoubleMatrix(2, 1, mxREAL); mxArray *in2 = mxCreateDoubleMatrix(2, 1, mxREAL); mxArray *out = mxCreateDoubleMatrix(2, 1, mxREAL); double *i1 = mxGetPr(in1); double *i2 = mxGetPr(in2); i1[0] = 1; i1[1] = 2; i2[0] = 3; i2[1] = 4; if(!mlfSUM(1, &out, in1, in2)){ cout<<"Could not execute function."<<endl; } double *res = mxGetPr(out); cout<<res[0]<<"; "<<res[1]<<endl; mxDestroyArray(in1); mxDestroyArray(in2); mxDestroyArray(out); cout<<"Terminating..."<<endl; libsumTerminate(); return 0; }
Вот и все. Можно запускать.
Выводы
Диплом выполнен, программа работает, я — счастливый инженер по информационным технологиям. Вроде бы все хорошо и радужно, но есть парочка нюансов:
- Размер архива MCR составляет 874 Мб.
- После запуска программы — начинают загружаться библиотеки MatLab и это откладывает запуск на пару секунд.
Правда есть и плюсы:
- Вы можете сосредоточить свое внимание на основной работе, не заботясь об оптимизации побочных функций и отлове ошибок в них.
- Скорость выполнения функций MatLab намного выше той, что вы смогли бы добиться за 3 месяца работы над проектом.
- Вы получаете всю силу MatLab в своем приложении.
- Время работы над проектом сокращается.
Если будет интересно напишу как я таким образом распознавал голосовые команды при помощи нейронных сетей.
