Can I pass a pointer to a matrix created in MATLAB to C via a MEX file and change the data in it?

3 views (last 30 days)
In MATLAB I would like to create an 1xN array of zeros, pass it to a C routine as an input argument, have the C routine update the (type double) values in the array (matrix in MATLAB). I would like to do this instead of having the MEX routine return a matrix (as is done in the example arrayProduct.c)
Is this possible, and if so, does anyone have any examples they would be willing to share?

Accepted Answer

Tommy Thomasson
Tommy Thomasson on 25 Mar 2018
Make the second to last line in step 2 this and it will work:
workOnExistingMatrix(mxGetPr(prhs[0]));
Here's the corrected MEX file:
//This is the MEX file (written in C)
#include "mex.h"
void workOnExistingMatrix(double* aMatrixCreatedInMatlab) {
aMatrixCreatedInMatlab[0] = 0.1234;
}
//The gateway function
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
//This works =)
workOnExistingMatrix(mxGetPr(prhs[0]));
}
  1 Comment
Jan
Jan on 26 Mar 2018
Be careful.
a = 1:10;
b = a;
yourMexFcn(b);
disp(a)
disp(b)
Both arrays are modified! A more evil example:
function main
a = zeros(1, 10);
subfunction(a);
disp(a)
end
function subfunction(b)
yourMexFcn(b)
disp(b);
end
There is no chance to see in the main function, why a(1) is modified. Do not underestimate the effects of shared data copies.

Sign in to comment.

More Answers (1)

Jan
Jan on 25 Mar 2018
Edited: Jan on 25 Mar 2018
This works directly, but it can have side-effects, because Matlab uses a copy-on-write strategy and shared data copies:
a = rand(100,100);
b = a;
Now the data pointer of a and b point to the same block of memory. A deep data copy is performed only, if b is modified:
b(1) = 0;
Now b has its own data.
Now to your question: If you provide a shared data copy to a C-Mex function and modify it, you touch both variables:
a = rand(100,100);
b = a;
YourInplaceOperation(b);
If you set e.g. b(1) to -1, a(1) is -1 also, because both variables share the data.
Therefore you have to check at first, if the input to the C-Mex function is a shared data copy. See James Tursa's FEX submissions:
Note that the method of shared data copies is not documented and the documentation of Matlab states, that it is not supported to modify the input data directly.
[EDITED] Keep in mind, that the input of your MEX can be a temporary variable:
a = rand(100,100);
YourInplaceOperation(a + 1);
Now modifying the input would be meaningless.
  2 Comments
Tommy Thomasson
Tommy Thomasson on 25 Mar 2018
Edited: Tommy Thomasson on 25 Mar 2018
Thanks Jan - that's helpful information, but it's still not clear how to pass a matrix pointer to a MEX function. Below is a simplified code example of what I want to do. For now, assume I'm not concerned about error checking the input arguments in the MEX gateway function.
Step 1: In MATLAB, I would do something like this:
%this is MATLAB code
myMatlabMatrix = zeros(1,5)
%workOnExistingMatrix is a MEX function defined in Step 2
workOnExistingMatrix(myMatlabMatrix)
Step 2: And here's the MEX file:
//This is the MEX file (written in C)
#include "mex.h"
void workOnExistingMatrix(double* aMatrixCreatedInMatlab) {
aMatrixCreatedInMatlab[0] = 0.1234;
}
//The gateway function
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, mxArray *prhs[]) {
//This doesn't work =(
//I assume I need a cast or a conversion of some sort
workOnExistingMatrix(prhs[0]);
}
Step 3: Back in MATLAB, I would then be able to do this:
>> %now we're back in MATLAB
>> myMatlabMatrix
myMatlabMatrix =
0.1234 0 0 0 0
>>% =)
I need help with the second-to-last line of the code in Step 2. Something else needs to happen here, but I haven't been able to figure out what.
James Tursa
James Tursa on 23 Apr 2018

What is missing is you need to pass the data pointer, not the mxArray pointer. E.g.,

workOnExistingMatrix(mxGetPr(prhs[0]));

Sign in to 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!