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);
}

