Прошла пора дипломов и я хочу поделиться своим рецептом его выполнения. Итак: тема сложная, времени мало, писать все «с нуля» или искать готовые библиотеки — нет большого желания, тем более что мне важна скорость работы системы, а от левых самописных библиотек можно ждать любого подвоха.
Надо сказать что размышлял я недолго и пришел к следующим выводам:
- Операционная система — тут думать особо не пришлось: т.к. я являюсь поклонником 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 в своем приложении.
- Время работы над проектом сокращается.
Если будет интересно напишу как я таким образом распознавал голосовые команды при помощи нейронных сетей.
Автор: Impuls