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

3 次查看(过去 30 天)
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?

采纳的回答

Tommy Thomasson
Tommy Thomasson 2018-3-25
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 个评论
Jan
Jan 2018-3-26
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.

请先登录,再进行评论。

更多回答(1 个)

Jan
Jan 2018-3-25
编辑:Jan 2018-3-25
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 个评论
Tommy Thomasson
Tommy Thomasson 2018-3-25
编辑:Tommy Thomasson 2018-3-25
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.

请先登录,再进行评论。

类别

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