Simple mex file crash?

조회 수: 1 (최근 30일)
MementoMori
MementoMori 2022년 3월 24일
편집: James Tursa 2022년 3월 25일
Hi I am studying mex files. I am trying to write a simple mex file that does a sum of two elements.
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
double *outData, *inData;
if(nrhs!=2) mexErrMsgTxt("Missing input data.");
inData = mxGetDoubles(prhs[0]);
outData = mxGetDoubles(plhs[0]);
outData[0] = inData[0]+inData[1];
}
If I try to run it, matlab crashes. There is some problem with the last line, have you any suggestion?

답변 (2개)

Rik
Rik 2022년 3월 24일
Despite what you indicate in the 4th line, inData and outData are not actually double*, they are mxDouble*.
As you can see in the documentation for mxGetDoubles, the output type is mxDouble*, which is a pointer type. You can add up two pointers, but that doesn't add up the values those pointers are pointing to.
A second problem with your code is that you assume inData will have two elements, while the rest of your post looks like you want to add up two inputs. The below code is the Matlab equivalent of what you're trying.
function outData=test(rhs1,rhs2)
if nargin~=2,error('Missing input data'),end
inData=rhs1;
outData=inData(1)+inData(2);
end

James Tursa
James Tursa 2022년 3월 25일
편집: James Tursa 2022년 3월 25일
You need to create the output variable yourself. plhs[0] doesn't exist until you create it, thus this line crashes:
outData = mxGetDoubles(plhs[0]);
because plhs[0] is garbage at this point and you are dereferencing an unitialized pointer.
Your code needs to look something like this instead if you want to add up two values from a single input:
/* Equivalent to m-code: Output = Input(1) + Input(2) */
/* The Input needs to have at least 2 elements */
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
double *outData, *inData;
if(nrhs!=1) mexErrMsgTxt("Missing input data.");
if(nlhs>1) mexErrMsgTxt("Too many outputs.")
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) ||
mxGetNumberOfElements(prhs[0])<2) {
mexErrMsgTxt("Need one full real double input with at least two elements")
}
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); /* You need to create plhs[0] first */
inData = mxGetDoubles(prhs[0]);
outData = mxGetDoubles(plhs[0]);
outData[0] = inData[0] + inData[1];
}
If you want to add up two scalar inputs, then the code would look something like this instead:
/* Equivalent to m-code: Output = Input1 + Input2 */
/* Both inputs need to have at least 1 element */
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
double *outData, *inData0, *inData1;
if(nrhs!=2) mexErrMsgTxt("Missing input data.");
if(nlhs>1) mexErrMsgTxt("Too many outputs.")
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) ||
mxGetNumberOfElements(prhs[0])<1) {
mexErrMsgTxt("Need two full real double inputs with at least one element each")
}
if( !mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) ||
mxGetNumberOfElements(prhs[1])<1) {
mexErrMsgTxt("Need two full real double inputs with at least one element each")
}
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); /* You need to create plhs[0] first */
inData0 = mxGetDoubles(prhs[0]);
inData1 = mxGetDoubles(prhs[1]);
outData = mxGetDoubles(plhs[0]);
outData[0] = inData0[0] + inData1[0];
}
As a side note, if you are just returning a scalar double from your mex routine then you might consider mxCreateDoubleScalar( ), which is a bit simpler to use than the pointer code you have written.

카테고리

Help CenterFile Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by