Matlab engine - cz. 2

W poprzedniej części tego mini-poradnika opisałem położenie bibliotek współdzielonych silnika Matlaba oraz flagi, które należy ustawić przy kompilacji programu. W tej części przedstawię krótki, dość prosty program, który zaprezentuje najczęściej używane funkcje silnika Matlaba: wykonywanie zadanej w postaci łańcucha znaków komendy Matlaba oraz przekazywanie do sesji Matlaba macierzy liczbowej.

W celu poinformowania programu o tym, że będziemy korzystać z funkcji API silnika Matlaba, dołączamy do programu odpowiedni plik nagłówkowy: #include "engine.h". Umożliwia on wykorzystanie funkcji API, dzięki którym możliwa staje się komunikacja z sesją Matlaba

Skoro już o tym mowa to warto taką sesję otworzyć. Służy do tego funkcja Engine *engOpen(const char *startcmd). Parametr startcmd jest komenda startową Matlaba, czyli katalog ze skryptem startowym Matlaba albo będzie się znajdował w zmiennej $PATH, albo należy podawać ścieżkę do skryptu startowego. Dokumentacja zastrzega sobie, że pod systemami z rodziny Windows parametr startcmd powinien być pusty (innymi słowy, wynosić NULL), jednak w moich programach zawsze zapominałem tego zmieniać i wszystko działało bardzo dobrze.

Funkcja służąca do otwierania sesji Matlaba zwraca wskaźnik typu Engine, który jest używany we wszystkich komendach, które odwołują się do silnika matematycznego środowiska Matlab. W przypadku zaś nieudanego otwarcia sesji Matlaba zwracane jest NULL. W celu zamknięcia otwartej sesji Matlaba (próba zamknięcia sesji nieotwartej może wywołać segfaulta) użyje się funkcji int engClose(Engine *ep). Zwraca ona 0 w przypadku powodzenia i 1 w przypadku niepowodzenia zamknięcia silnika.

Do przekazywania do Matlaba poleceń służy funkcja int engEvalString(Engine *ep, const char *command), która do sesji Matlaba, na którą wskazuje wskaźnik *ep, przekazuje polecenie określone łańcuchem znaków command. Zwracane wartości to 0 (poprawne wykonanie polecenia) lub 1 (wystąpienie błędu).

Drugą najczęściej używaną funkcją jest int engPutVariable(Engine *ep, const char *name, const mxArray *pm). Pozwala ona na wprowadzenie do obszaru zmiennych Matlaba tablicy typu mxArray. Zadeklarowanie takiej tablicy wymaga posiadania w pamięci innej tablicy (np. dwuwymiarowej tablicy liczb zmiennoprzecinkowych), która zostanie przekopiowana przy użyciu np. funkcji memcpy. Ponieważ kilka linijek kodu jest wartych więcej niż tysiąc słów, to w celu lepszego zaprezentowania typowego użycia funkcji engPutVariable poniżej zostaje zamieszczony fragment kodu odpowiadający za utworzenie w uruchomionej sesji Matlaba zmiennej matlabArray. Reprezentować ona będzie dwuwymiarową macierz 2 na 3 kolejnych elementach równych 1, 2, 3, …

Engine *ep;
double MyArray[2][3] = { {1.0, 2.0, 3.0}, {4.0, 5.0, 6.0} };

// Deklaracja zmiennej array
mxArray *array = NULL;

// Tu następuje otwarcie sesji Matlaba itp.
// Inicjalizacja zmiennej array
array = mxCreateDoubleMatrix(2, 3, mxREAL);
memcpy((void *)mxGetPr(array), (void *)MyArray, sizeof(MyArray));

// Przesłanie zmiennej array do otwartej sesji Matlaba 
// pod nazwą matlabArray. 
engPutVariable(ep, "matlabArray", array);

// Dalsza część programu... `

Na tym krótkim fragmencie skończymy. W następnej części połączone zostaną wszystkie informacje zdobyte w tej i poprzedniej części tego krótkiego poradnika silnika Matlaba. W wyniku tego powstanie prosty program konsolowy prezentujący opisane funkcje API silnika.