在 mex 文件中,我无法通过 matlab2016a 中的指针覆盖标量,尽管我可以覆盖 2013a 中的标量以及 2016a 中的数组

In mex file, I can't overwrite scalar through the pointer in matlab2016a, although I can overwrite the scalar in 2013a and also the array in 2016a

[环境]

OS: OSX10.11 和最大OS Sierra(10.12)

MATLAB:matlab2013a 和 matlab2016a

Xcode:xcode7 和 xcode8


在我的工作中,我必须使用旧包中的以下mex文件。

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

这个mex文件是通过指针覆盖标量和矩阵部分的函数

例如在 matlab2013a 命令中 window(matlab2013a 中的标量)

a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);

变量"a"变为“3”。

例如在 matlab2013a 和 matlab2016a 命令中 window(matlab2013a 和 matlab2016a 中的矩阵)

a = [1, 2];
destructiveMatrixWriteAtIndices(a, 3, 0);

变量"a"变为“[3, 2]”。

例如在 matlab2016a 命令中 window(matlab2016a 中的标量)

a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);

变量"a"变为“1”!为什么?

我也使用了 lldb,并揭示了这段代码的奇怪行为。

在 matlab2013a 和 matlab2016a 中,当我 运行 以下代码段时。

a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);

lldb在两个matlab中都在mex函数的末尾显示了“*mtx = 3”,但是mex函数无法传递结果(*mtx = 3,或prhs[0] = 3)通过matlab2016a中唯一的指针。

这是非常奇怪的行为!

※我知道这个mex函数很危险,但是这个mex函数在我必须使用的包中的某些地方被使用了。因此,我必须修复这个 mex 文件并在 matlab2016a 中制作包 运行.

请帮助我。

我很确定您不是要修改 mex 函数中的输入数组。此处有更多详细信息 Does Matlab ever copy data passed to a mex function?。 "matlab" 解决方案可能是 return 修改后的数组作为 mex 的输出,而不是就地修改。