Hi,
I am writing an Engine application in C, which will be standalone eventually, but I would also like to call the routines via a mex interface if possible. So, at the moment I have a rather convoluted process of a mex file creating a separate instance of the Matlab engine, which I want to talk to (eventually this will be multiple engines via MPI). I'm doing this using Matlab coder.
So, I have the test code below which is trying to open a new engine from a mex file and talk to it...
function outp = engTest()
params = [1, 2, 3, 4, 5, 6, 7, 8];
paramsLen = 8;
funName = 'total = debugMfile(params,bulk_in,bulk_out,contrast);';
pathCall = 'cd(''/home/arwel/Documents/coding/cevalTests/mlEng'');';
bulkIn = 2.073e-6;
bulkOut = 6.35e-6;
contrast = 1.0;
path = '/home/arwel/Documents/coding/cevalTests/mlEng';
incPath1 = '/usr/local/MATLAB/R2015b/extern/include';
incPath2 = '/usr/include/openmpi';
linkPath1 = '/usr/local/MATLAB/R2015b/bin/glnxa64';
linkFile1 = 'libeng.so';
linkFile2 = 'libmx.so';
source1 = 'matlabCallFun.c';
source2 = 'matlabEngine_demo.h';
libPriority = '';
libPreCompiled = true;
libLinkOnly = true;
coder.cinclude(source2);
coder.updateBuildInfo('addSourceFiles',source1);
coder.updateBuildInfo('addSourcePaths',path);
coder.updateBuildInfo('addIncludePaths',incPath1);
coder.updateBuildInfo('addIncludePaths',incPath2);
coder.updateBuildInfo('addLinkObjects',linkFile1,linkPath1,libPriority,libPreCompiled,libLinkOnly);
coder.updateBuildInfo('addLinkObjects',linkFile2,linkPath1,libPriority,libPreCompiled,libLinkOnly);
outp = zeros(2,3);
coder.ceval('matlabCallFun', params, paramsLen, funName, pathCall, bulkIn, bulkOut, contrast, coder.wref(outp));
end
and matlabCallFun.c as follows.....
/*
* matlabCallFun.c
*
* Created on: 21 Jul 2017
* Author: arwel
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "engine.h"
void matlabCallFun(double params[], int arrayLen, char *funName, char *pathCall, double bulkIn, double bulkOut, double contrast, double *sum) {
static Engine *ep;
static double engStatus = 0;
mxArray *result = NULL;
mxArray *PARAMS = NULL;
mxArray *BULKIN = NULL;
mxArray *BULKOUT = NULL;
mxArray *CONTRAST = NULL;
mxArray *FNAME = mxCreateString(funName);
double *s;
if(engStatus == 0) {
ep = engOpen("");
if(ep==0) {
printf("Connecton to Matlab Engine failed\n");
}
else {
printf("Connecton to Matlab Engine succeeded!\n");
engEvalString(ep,(void *)pathCall);
engStatus = 1;
}
}
PARAMS = mxCreateDoubleMatrix(1,arrayLen,mxREAL);
memcpy((void *)mxGetPr(PARAMS), (void *)params, arrayLen*sizeof(double));
engPutVariable(ep,"params",PARAMS);
BULKIN = mxCreateDoubleMatrix(1,1,mxREAL);
memcpy((void *)mxGetPr(BULKIN), &bulkIn, 1*sizeof(double));
engPutVariable(ep,"bulk_in",BULKIN);
BULKOUT = mxCreateDoubleMatrix(1,1,mxREAL);
memcpy((void *)mxGetPr(BULKOUT), &bulkOut, 1*sizeof(double));
engPutVariable(ep,"bulk_out",BULKOUT);
CONTRAST = mxCreateDoubleMatrix(1,1,mxREAL);
memcpy((void *)mxGetPr(CONTRAST), &contrast, 1*sizeof(double));
engPutVariable(ep,"contrast",BULKOUT);
engEvalString(ep,(void *)funName);
result = engGetVariable(ep,"total");
s = (double *)mxGetData(result);
memcpy(sum, s, 8*sizeof(double));
engClose(ep);
}
When I compile this, and try to run
codegen engTest -o engTest_mex
y = engTest_mex
I get a seg fault, and the following in the relevant terminal window....
Connecton to Matlab Engine succeeded!
cd('/home/arwel/Documents/coding/cevalTests/mlEng');7
|
Error: The input character is not valid in MATLAB statements or expressions.
total = debugMfile(params,bulk_in,bulk_out,contrast);,YǂZ
|
Error: The input character is not valid in MATLAB statements or expressions.
What am I missing here?
Cheers,
Arwel
p.s.
The fun being called is....
function total = debugMfile(params,bulk_in,bulk_out,contrast)
s = sum(params);
total = [s bulk_out bulk_in ; 4 5 6];
save debugMfileVars.mat
end