In mex file, I can't overwrite scalar value through the pointer in matlab2016a, although I can overwrite the scalar value through the pointer in matlab2013a and I can also overwrite the array through the pointer in matlab2016a.
Show older comments
[environment]
OS: OSX10.11 and maxOS Sierra(10.12)
MATLAB: matlab2013a and matlab2016a
Xcode: xcode7 and xcode8
------------------------------------------------------
In my work, I must use the following mex file in the old package.
//destructiveMatrixWriteAtIndices.c
//------------------------------------------------------
#include <matrix.h> /* Matlab matrices */
#include <mex.h>
#include <stddef.h> /* NULL */
#define notDblMtx(it) (!mxIsNumeric(it) || !mxIsDouble(it) || mxIsSparse(it) || mxIsComplex(it))
void mexFunction(int nlhs, /* Num return vals on lhs */
mxArray *plhs[], /* Matrices on lhs */
int nrhs, /* Num args on rhs */
const mxArray *prhs[] /* Matrices on rhs */
)
{
double *mtx;
double *newValues;
double *doubleStartIndex;
int i, startIndex, size;
mxArray *arg;
if (nrhs != 3) mexErrMsgTxt("requires 3 arguments.");
/* ARG 1: MATRIX */
arg = prhs[0];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
mtx = mxGetPr(arg);
arg = prhs[1];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
newValues = mxGetPr(arg);
size = (int) mxGetM(arg) * mxGetN(arg);
arg = prhs[2];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
doubleStartIndex = mxGetPr(arg);
startIndex = (int) doubleStartIndex[0];
for (i=0; i<size; i++)
{
mtx[i+startIndex] = newValues[i];
}
return;
}
//------------------------------------------------------
This mex file is the function to overwrite the scalar and the part of matrix through the pointer.
e.g. in matlab2013a command window (scalar in matlab2013a)
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "3".
e.g. in matlab2013a and matlab2016a command window (matrix in matlab2013a and matlab2016a)
a = [1, 2];
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "[3, 2]".
e.g. in matlab2016a command window (scalar in matlab2016a)
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "1"! Why?
I also used the lldb, and revealed the strange behavior of this code.
In matlab2013a and matlab2016a, when I run the following snippet.
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
The lldb revealed "*mtx = 3" at the end of the mex function in both matlab, but the mex function couldn't pass the result(*mtx = 3, or prhs[0] = 3) through the pointer in the only matlab2016a.
It's very strange behavior!
※I have understood that this mex function is very danger, but this mex function was used at some points in the package that I must use. Therefore, I must fix this mex file and make the package run in matlab2016a.
Please help me.
2 Comments
James Tursa
on 7 Oct 2016
Did you recompile this mex routine under R2016a? Or are you using the mex routine you compiled in an earlier version? I would try recompiling if you haven't yet. I would also put this statement at the end of your mex routine to verify that the double data did in fact get changed in the mex routine:
mexCallMATLAB(0,NULL,1,prhs,"disp");
What is the purpose of this mex routine? I.e., why can't you just do a regular indexed assignment at the m-file level to accomplish this? Are you trying to force in-place data replacement even if the variable is a shared-data-copy of another variable? Or what?
c0maru
on 9 Oct 2016
Accepted Answer
More Answers (1)
James Tursa
on 7 Oct 2016
One possibility is that MATLAB is not passing "a", but a copy of "a" to the mex routine. In my experience MATLAB always has passed the actual variables to the mex routine, but maybe this has changed and now MATLAB passes a temporary copy of scalars. Do the following to make sure you are getting the original "a" passed to the mex routine:
format debug
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
Then in the mex routine print out the address of prhs[0], e.g.,
mexPrintf("prhs[0] = %p\n",prhs[0]);
and compare this to the variable structure address that is printed out at the m-file level. They should be the same, but maybe in R2016a they aren't for some reason. Let me know what you find out. This would be a real bummer if the argument passing mechanism for mex files has changed!
1 Comment
Categories
Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!