Esse post visa comentar (e ajudar alguém) o caminho para utilizar a MatLab Engine API, não vou explicar os detalhes de funcionamento - pois constam no link. Mas basicamente ela serve para possibilitar a utilização do motor do MatLab por aplicações externas.
O ambiente utilizado foi:
- Windows 7 64 bits instalado numa máquina virtual usando VMWare, é grátis para fins não comerciais.
- MatLab Student 2013a Versão 32 bits
- Visual Studio 2012 Express.
- openFrameworks - http://openframeworks.cc/ - versão 0.8.3 para Windows - Visual Studio
Foram utilizados os seguintes links para ajudar:
Após todas as ferramentas instaladas,
- Criar um projeto usando o projectGenerator do openFrameworks.
- Entrar no Solution criado pelo projectGenerator
- Ajustar IDE.
- Dentro do Visual Studio, abra as Propriedades (Properties) da solução criada.
- Em Configuration Properties -> Debugging -> Command, adicionar o caminho PATH=$C:Program Files (x86)MATLABR2013abin . Lembrem que instalei a versão 32bits do Matlab. DICA: Crie uma variável MATLABROOT que direcione para o raiz do MatLab - facilita.
- Em Configuration Properties -> C/C++ -> General, adicione os endereços dos diretórios com includes em “Additional Include Directories”:
- C:Program Files %28×86%29MATLABR2013aexternincludewin32;
- C:Program Files %28×86%29MATLABR2013aexterninclude
- Em Configuration Properties -> C/C++ -> Precompiled Headers verifique se Precompiled Headers está em “Not Using Precompiled Headers”
- Em Configuration Properties -> Linker -> General, adicione o endereço em “Additional Library Directories”:
- C:Program Files %28×86%29MATLABR2013aexternlibwin32microsoft
- Em Configuration Properties -> Linker -> Input, adicionar as dependencias em “Additional Dependencies”,
- libmx.lib
- libmat.lib
- libeng.lib
- Ajustar SO.
- Vá em “Configurações Avançadas de Sistema” -> “Variáveis de Ambiente”, em Variáveis do sistema, encontre a variável PATH, e adicione:
- C:Program Files (x86)MATLABR2013aruntimewin32;
- C:Program Files (x86)MATLABR2013abin;
- C:Program Files (x86)MATLABR2013abinWIN32
- Aproveite e crie uma variável de usuário MATLABROOT apontando para:
- C:Program Files (x86)MATLABR2013a
- Vá em “Configurações Avançadas de Sistema” -> “Variáveis de Ambiente”, em Variáveis do sistema, encontre a variável PATH, e adicione:
Arquivos exemplos da Engine API encontram-se dentro: C:Program Files (x86)MATLABR2013aexternexampleseng_mat
Para testar o ambiente utilizei o engdemo.cpp, copiado na integra aqui:
Seguindo, no openFrameworks, no arquibo ofApp.h, inclua os cabeçalhos, engine.h e matrix.h e faça a instancia do apontamento para a Engine, o trecho de código do cabeçalho segue abaixo
#pragma once #include "engine.h" #include "matrix.h" #include "ofMain.h" #define BUFSIZE 256 class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void keyPressed(int key); void keyReleased(int key); void mouseMoved(int x, int y ); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); Engine* pEng; };
No arquivo ofApp.cpp, para este teste, copie o trecho do exemplo dado pelo MatLab dentro do ofApp::setup();
//-------------------------------------------------------------- void ofApp::setup(){ Engine *ep; mxArray *T = NULL, *result = NULL; char buffer[BUFSIZE+1]; double time[10] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 }; cout< /* * Call engOpen with a NULL string. This starts a MATLAB process * on the current host using the command "matlab". */ if (!(ep = engOpen(""))) { fprintf(stderr, "nCan't start MATLAB enginen"); exit(); } cout< /* * PART I * * For the first half of this demonstration, we will send data * to MATLAB, analyze the data, and plot the result. */ /* * Create a variable for our data */ T = mxCreateDoubleMatrix(1, 10, mxREAL); memcpy((void *)mxGetPr(T), (void *)time, sizeof(time)); /* * Place the variable T into the MATLAB workspace */ engPutVariable(ep, "T", T); /* * Evaluate a function of time, distance = (1/2)g.*t.^2 * (g is the acceleration due to gravity) */ engEvalString(ep, "D = .5.*(-9.8).*T.^2;"); /* * Plot the result */ engEvalString(ep, "plot(T,D);"); engEvalString(ep, "title('Position vs. Time for a falling object');"); engEvalString(ep, "xlabel('Time (seconds)');"); engEvalString(ep, "ylabel('Position (meters)');"); /* * use fgetc() to make sure that we pause long enough to be * able to see the plot */ printf("Hit return to continuenn"); fgetc(stdin); /* * We're done for Part I! Free memory, close MATLAB figure. */ printf("Done for Part I.n"); mxDestroyArray(T); //engEvalString(ep, "close;"); /* * PART II * * For the second half of this demonstration, we will request * a MATLAB string, which should define a variable X. MATLAB * will evaluate the string and create the variable. We * will then recover the variable, and determine its type. */ /* * Use engOutputBuffer to capture MATLAB output, so we can * echo it back. Ensure first that the buffer is always NULL * terminated. */ buffer[BUFSIZE] = ''; engOutputBuffer(ep, buffer, BUFSIZE); while (result == NULL) { char str[BUFSIZE+1]; /* * Get a string input from the user */ printf("Enter a MATLAB command to evaluate. This command shouldn"); printf("create a variable X. This program will then determinen"); printf("what kind of variable you created.n"); printf("For example: X = 1:5n"); printf(">> "); fgets(str, BUFSIZE, stdin); /* * Evaluate input with engEvalString */ engEvalString(ep, str); /* * Echo the output from the command. */ printf("%s", buffer); /* * Get result of computation */ printf("nRetrieving X...n"); if ((result = engGetVariable(ep,"X")) == NULL) printf("Oops! You didn't create a variable X.nn"); else { printf("X is class %stn", mxGetClassName(result)); } } /* * We're done! Free memory, close MATLAB engine and exit. */ printf("Done!n"); mxDestroyArray(result); engClose(ep); }