Создание автономного C-приложения с библиотекой matlab
Иногда нужно сделать приложение, которое общается с неким девайсом и выполняет сложные математические расчеты. Конечно, можно написать свои библиотеки или найти библиотеки сторонних разработчиков, но зачем, если все уже написано за нас? Намного проще написать матлабовскую функцию, отладить ее и использовать в своем приложении.
MATLAB Component Runtime
Программа, созданная на каком-либо языке, требует для своего выполнения определенный набор служб – среду выполнения. Компилятор MATLAB не имеет математических библиотек. Вместо них используется среда выполнения MATLAB, называемая MCR (MATLAB Component Runtime). Она состоит из набора dll-библиотек и обеспечивает полную поддержку языка MATLAB.
Для установки среды выполнения компоненты MATLAB нужно использовать файл MCRInstaller.exe, который расположен в следующем каталоге %matlabroot%\toolbox\compiler\deploy\win32. При выполнении этого файла начинается обычный процесс установки Windows-приложения (никаких серийных номеров и регистрации не требуется). Библиотеки MCR по умолчанию устанавливаются в каталог C:\Program Files\MATLAB\MATLAB Component Runtime\v76, где подкаталог «v76» соответствует версии 7.6 среды MCR, другая версия MCR уста навливается независимо в соседний каталог, например, «.\v74» – от MATLAB R2006b. При работе приложения используется та версия MCR, на которой был создан компонент MATLAB. Для перехода на другую версию компонент должен быть перекомпилирован.
Обертки
Matlab может генерировать несколько оберток для ваших программ:
-
С main – файлы с процедурой main на C
-
C WinMain – файлы с процедурой main на C
-
CPP Main – dll библиотека, содержащая класс с функционалом вашего приложения
-
C shared lib — dll библиотека, содержащая С-функции
-
COM – COM обьект.
Самый простой, по моему мнению способ использовать ваш m-код в С-программе — C shared lib. Будем использовать его.
Для демонстрации, напишем простую программу
function [double_freq]=test(freq) t = 0:0.001:1; val = sin( 2*pi*freq*t ); plot(t, val); double_freq = 2*freq; end
В ней есть все основные элементы – график, передача данных в приложение и прием из приложения.
Компилятором matlab нельзя компилировать непосредственно встроенные функции. Для того, чтобы их использовать необходимо создать промежуточный m-файл.
Шаг 1: Настройка линкера.
Для того, чтобы получить на выходе компилятора matlab статически подключаемую библиотеку, необходимо настроить линкер, которым она будет собираться. Конечно, собрать lib можно и в ручную или использовать для этого специальную утилиту. Но мне так было удобнее.
Проделаем следующие действия:
>> mbuild -setup
Please choose your compiler for building standalone MATLAB applications:
Would you like mbuild to locate installed compilers [y]/n? y
Select a compiler:
[1] Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2008b\sys\lcc
[2] Microsoft Visual C++ 2008 in C:\Program Files\Microsoft Visual Studio 9.0
[0] None
Compiler: 2
Please verify your choices:
Compiler: Microsoft Visual C++ 2008
Location: C:\Program Files\Microsoft Visual Studio 9.0
Are these correct [y]/n? y
Trying to update options file: C:\Documents and Settings\BSVi\Application Data\MathWorks\MATLAB\R2008b\compopts.bat
From template: C:\PROGRA~1\MATLAB\R2008b\bin\win32\mbuildopts\msvc90compp.bat
Done . . .
Шаг 2: Сборка библиотеки
Выполняется следующей командой:
mcc -W lib:test -T link:lib test
ключ –W lib:test означает, что мы хотим собрать C shared lib
ключем -T link:lib мы просим по собрать из полученных в результате компиляции файлов статическую библиотеку.
Test – это имя .m-файла.
В результате компиляции появляются следующие файлы:
- Test.lib – статическая библиотека. Ради нее все и затевалось.
- Test.dll – динамический вариант.
- Test.c — файл обертки C
- Test.exports – список экспортируемых функций
- Test.h – заголовочный файл для экспортируемых функций
- Test_mcc_component_data.c — C_файл, содержащий данные, необходимые MCR для нициализации и использования приложения.
- readme.txt — содержит необходимую информацию для инсталляции приложения
Шаг 3: Подготавливаем среду к компиляции.
Добавляем пути к .h файлам matlab
Добавляем нашу статическую библиотеку и статические библиотеки matlab:
Эти библиотеки можно найти по пути %matalbroot%\extern\lib\win32\microsoft\
Шаг 4: Пишем приложение
Правила написания кода приложения. Для использования созданной Компилятором MATLAB библиотеки в приложении, код С — программы должен иметь следующую структуру:
1. Включение в приложение созданного заголовочного файла для каждой библиотеки <lib_name>.h.
2. Объявление переменных.
3. Вызов функции mclInitializeApplication для инициализации среды исполнения MCR MATLAB. Необходимо вызвать эту функцию один раз в приложении, и это нужно сделать перед вызовом любых других MATLAB-функций.
4. Вызов функции <lib_name>Initialize() библиотеки. Эта функция возвращает значение true при успешной инициализации и false – в случае отказа.
5. Вызов экспортируемых функций библиотеки. Это – основная часть программы. При этом следует использовать mx-интерфейс C, чтобы обработать параметры ввода и вывода функций. Если приложение отображает график в окне MATLAB, то нужно включить вызов mclWaitForFiguresToDie(NULL) перед вызовом функций Terminate и mclTerminateApplication.
6. Вызов функции <lib_name>Terminate() завершения библиотеки, когда приложение больше не нуждается в данной библиотеке. Эта функция освобождает ресурсы, связанные с ее экземпляром MCR.
7. Вызов функции mclTerminateApplication уничтожает MCR
8. Освобождение переменных, закрытие файлов и т.д., выход.
Передача и прием параметров
MATLAB работает с только единственным типом объекта: массивом MATLAB. Все переменные MATLAB, включая скаляры, векторы, матрицы, строки, массивы ячейки, структуры, и объекты, сохраняются как массивы MATLAB. Для взаимодействия языков программирования C и MATLAB создан соответствующий типу MATLAB тип данных mxArray C.
Справка matlab содержит полное руководство по работе с mxArray. Его можно найти по запросу “C and Fortran API Reference”.
Пример программы
#include "stdafx.h" #include "stdio.h" #include "conio.h" #include "test.h" int _tmain(int argc, _TCHAR* argv[]) { mxArray *in, *out; printf( "Loading... \n"); if( !mclInitializeApplication(NULL,0) ) { printf("Could not initialize the application.\n"); _getch(); return -1; } in = mxCreateDoubleScalar( 1.123 ); out = mxCreateDoubleScalar( 0 ); if ( !testInitialize() ) { printf("Could not initialize the library.\n"); _getch(); return -2; } else { if ( !mlfTest( 1, &out, in ) ) { printf("Could not execute function.\n"); _getch(); return -3; } _getch(); printf("Double frequency is %f \n", mxGetScalar(out)); testTerminate(); mxDestroyArray(in); mxDestroyArray(out); } printf("Terminating... \n"); mclTerminateApplication(); _getch(); return 0; }
Ага, она работает. Показывает график и выдает.
MATLAB:I18n:InconsistentLocale — The system locale setting, Russian_Russia.1251, is different from the user locale setting, English (United States)_United States.1252.
Loading…
Double frequency is 2.246000
Terminating…
а у меня на втором шаге ошибка (((
не могу понять в чем дело.
>> mcc -W lib:test -T link:lib test
Input file named twice. Ignored.
cannot open c:\docume~1\
D:\PROGRA~1\MATLAB\R2008A\BIN\MEX.PL: Error: Link of ‘test.dll’ failed.
Error: An error occurred while shelling out to mbuild (error code = 2).
Unable to build executable (specify the -v option for more information).
??? Error using ==> mcc
Error executing mcc, return status = 1.
Похоже, малтаб просто не может использовать ваш длинный путь c:\docume~1\
test_mcc_component_data.c : fatal error C1853: файл предкомпилированного заголовка «Debug\test.pch» создан в предыдущей версии компилятора или предкомпилированный заголовок C++ используется из C (или наоборот)
Что-бы это значило?
Это какая-то особенность вашего компилятора.
Имеем:
1. Matlab 2009b x64
2. VisualStudio 2008 SP1
Повторяю все один в один. О какой особенности идет речь?
Я не в курсе, с такой проблемой не встречался. Посмотертие — есть ли в заголовочных фалйах обертка
extern «C» {
….. все содержимое заголовка…
}
Была такая же ошибка, убрал галочку при создании проекта «Предварительно скомпилированный заголовок» проект запустился. Но почему то пришлось скидывать файл test.h в папку проекта, иначе не видел его. И когда запустился выдавал ошибку «Could not initialize the library» побороть так и не смог.
Есть соображения?)
удалил файл test.c из проекта, все запустилось, все работает
я конечно понимаю что все это очень даже не плохо, но что то у меня не получается! Я не супер профи ( хотя очень бы хотел научится чему нибудь) но пожалуйста можно по подробнее как например добовлять пути к .h файлам например… я бы хотел создать независиму программу (.exe приложение) с помощью matlab без лишних .dll библиотек. буду очнь признателен если кто нибудь пможет!
Без «лишних» dll не получится — ведь в них сидит виртульная машина матлаба. Как добавлять пути зависит от используемого компилятора. Как это делать для visual studio я показал в статье (ну потратьте 3 минуты и найдите этот диалог)
да да я читал! В matlab есть функция компиляции в с++ builder. но к сожалению без аналогичной версии matlab загрузить созданную программку не получается, а если и получается то необходим весь пакет dll библиотек зкоторые занимают 150 — 170 mb что к большому сожалению очень плохо, да и не нужно т.к. результат себя не оправдывает! ну все же я думаю есть какие нибудь обходные пути для выбора неоходимых dll. Они же все равно не все используются… главное чтобы «взаимосвязи» между ними не было. или я не прав? а если не прав, то как посоветуйте выийти из ситуции и создать .exe приложение не большого размера?
150-170 мб — это ядро матлаба. Без него матлабовские программы не работают. Это как java-машина. Не обязательно постоянно таскать с собой весь набор этих библиотек — достаточно поставить в систему их один раз как это сделать написано в хелпе матлаба. Создать приложение без длл можно было в шестой версии матлаба (насколько я помню), в новых версиях такой возможности нет и не предвидеться.
А можно делать Guide приложения автономными?
Я не знаю, что это такое.
Если в matlabe набрать guide то появиться возможность создавать оконные приложения с расширением .fig и .m
В guide можно делать автономные приложения. Но не удобно, если хочешь делать большую хорошую программу. Чтобы они работали тоже надо использовать файл MCRInstaller.exe.
Здравствуйте. У меня возник вопрос по матлабу. а именно по компиляции м-файлов в библиотеку с++
вопрос заключается в следующем.
для компиляции библиотеки я использую deploytool
выбираю matlab compiler/C++ shared library
добавляю в проект свой м-файл.
нажимаю кнопку build.
в ответ появляется сообщение, что нужно выбрать компилятор командой mbuild -setup.
я запускаю эту команду, но там нет компилятор visual studio C++.
выводится такой текст:
Select a compiler:
[1] Lcc-win32 C 2.4.1 in F:\PROGRA~1\MATLAB\R2008a\sys\lcc\bin
[0] None
Вопрос: как добавить компилятор Visual studio C++ в matlab?
Буду очень признателен Вам за ответ. Уже третий день ищу информацию в интернете — ничего нет.
Спасибо.
Пожалуйста, подскажите возможную причину сбоя.
После запуска mcc -W lib:test -T link:lib test (Шаг 2), появляются
Test.lib ; Test.dll ; Test.c ; Test.exports ; Test.h ; readme.txt
и два дополнительных файла Test.exp и mccExcludedFiles.log
(но нет Test_mcc_component_data.c)
Как сгенерировать Test_mcc_component_data.c?
К сожалению, нет. Я сейчас другим занимаюсь и у меня даже нет матлаба.