Assigning mxUint16 variable to plhs[0]

26 次查看(过去 30 天)
I am stuck trying to assign uint16 variable to my MEX output. I boiled it down to the following code, which compiles just fine but still crashes Matlab:
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxUint16 variable;
variable = (mxUint16)127;
mwSize dims[2];
dims[0] = 1;
dims[1] = 1;
plhs[0] = mxCreateNumericArray(2, dims, mxUINT16_CLASS, mxREAL);
mxSetUint16s(plhs[0], &variable);
}
Any ideas what could be wrong?

采纳的回答

James Tursa
James Tursa 2021-12-3
编辑:James Tursa 2021-12-3
You cannot attach native C/C++ memory to an mxArray. The MATLAB API "mxSetEtc" functions check to see that the memory addresses passed in are from the MATLAB Memory Manager, and if not then they crash with an assertion fault. Even if it didn't crash right away, note that the memory address you are passing in comes from a local stack variable (i.e., &variable points to stack memory), and this memory address becomes invalid as soon as the mex function returns to the caller. To do what you are trying to do, you need to get the memory from the MATLAB Memory Manager. E.g.,
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxUint16 *variableptr; // a local pointer to mxUint16
variableptr = (mxUint16 *) mxMalloc(sizeof(*variableptr)); // alloc MATLAB memory behind the pointer
*variableptr = (mxUint16)127; // assign value to memory behind pointer
mwSize dims[2];
dims[0] = 1;
dims[1] = 1;
plhs[0] = mxCreateNumericArray(2, dims, mxUINT16_CLASS, mxREAL);
mxFree(mxGetUint16s(plhs[0])); // free the plhs[0] data memory that is currently there
mxSetUint16s(plhs[0], variableptr); // attach the MATLAB alloc memory pointer
}
In the above example, the memory to store the data value 127 is allocated by the MATLAB Memory Manager, so it is safe to attach this directly to an mxArray. The mxSetUint16s( ) function call will remove this data memory from the garbage collection list, so it will in effect become persistent with this call and remain valid when the mex function returns to the caller. The mxFree( ) function call is necessary to avoid a memory leak.
Another way to do this is to manipulate the plhs[0] data pointer directly. E.g.,
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mwSize dims[2];
dims[0] = 1;
dims[1] = 1;
plhs[0] = mxCreateNumericArray(2, dims, mxUINT16_CLASS, mxREAL);
*mxGetUint16s(plhs[0]) = (mxUint16)127; // assign value to memory behind data pointer
}
Here we are simply getting the current data pointer and then stuffing that location with our 127 value.
  1 个评论
Dries Neirynck
Dries Neirynck 2021-12-6
Thank you for your answer.
You cannot attach native C/C++ memory to an mxArray.
I obviously missed that bit. It could be good to add this infor to the "Fill mxArray in C MEX File" of the documentation.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Write C Functions Callable from MATLAB (MEX Files) 的更多信息

产品


版本

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by