Why doesn't the MEX function call from MATLAB match the signature in the MEX file?

2 次查看(过去 30 天)
After completing the "Create A C Source MEX File" tutorial https://www.mathworks.com/help/matlab/matlab_external/standalone-example.html, I'm not clear on how the mapping of function signatures works from MATLAB to C.
In the example (arrayProduct.c), there are two functions in the example MEX file. One is (void) arrayProduct(double, double*,double*,int). The second is the required entry function which has a void return type and arguments (int, mxArray*, int, const mxArray*). When calling the function from MATLAB however, the signature doesn't match either of the functions in the MEX file: [returns matrix] arrayProduct(number,Matrix).
Intuitively, I would expect the function arrayProduct in the .c file to have the same signature as what would be called from MATLAB.
The question is - given a random MEX (*.c) file, how can I tell what the function signature needs to be when called from MATLAB?

采纳的回答

Walter Roberson
Walter Roberson 2018-3-25
Normal mex functions need to have parameters for the number of output arguments, the pointers to the output arguments, the number of input arguments, and the pointers to the input arguments.
  4 个评论
James Tursa
James Tursa 2018-3-28
编辑:James Tursa 2018-3-28
Some comments:
1) It doesn't matter what the classes of the arguments are. MATLAB will pass in the nlhs, plhs[], nrhs, and prhs[] to the mex routine in that order. The input prhs[] of course already contains pointers to existing mxArray variables from the caller (could be the original caller variables or could be shared data copies of the original caller variables depending on the MATLAB version). The output plhs[] is simply an uninitialized pointer array and it is up to the C code to fill it in. It is up to the C code to check that the number and class of the input arguments matches what is expected, and throw an error if they don't match expectations.
2) MATLAB always allocates at least one plhs[] for output, even when nlhs = 0. I.e., you can always assign an output mxArray pointer to plhs[0] even when nlhs = 0. That way the C mex routine can always be assured that it can generate a single output that will go into ans in this case.
3) Your double code is incorrect. The prhs[] and plhs[] contain pointers to mxArray structures, not doubles. So these lines probably wouldn't even compile:
double argument1 = prhs[0];
etc.
The compiler would complain that you are trying to convert a mxArray pointer to a double. What you need to do is get the pointer to the data area from the mxArray with an API function (either mxGetPr or mxGetDoubles depending on your version of MATLAB). E.g.,
double *argument1 = mxGetPr(prhs[0]); // for R2017b memory model
or
double *argument1 = mxGetDoubles(prhs[0]); // for R2018a memory model

请先登录,再进行评论。

更多回答(1 个)

Jan
Jan 2018-3-25
编辑:Jan 2018-3-25
There is no "function signature" when you call a C-mex function, because there is none in Matlab also. Example:
function [a, b] = MyFunc(c, d)
switch nargin
case 0
a = 'No input';
case 1
a = pi;
b = rand(10);
case 2
if nargout == 2
a = d;
b = c;
else
a.both = [c,d];
end
end
You can expand this by varargin and varargout completely flexible. And the same can happen in C-Mex functions also. Both M- and C-Mex function get a set of input arguments and reply a list of output arguments. But the type of inputs and outputs is not fixed.
Of course using well defined inputs equivalent to a "signature" of inputs is useful in many cases, but not required, see e.g. the plot command, which accepts a variety of inputs.
Why doesn't the MEX function call from MATLAB match the signature
in the MEX file?
Short answer: Because it is a Matlab-like call, which differs from C.
  1 个评论
Tommy Thomasson
Tommy Thomasson 2018-3-25
Maybe my terminology is wrong, but the use of "signature" here refers to the definition of the inputs and outputs of a function or method.
I see what you're saying, but disagree because both C functions and MATLAB functions do have their own signatures. The fact that they have different numbers of arguments is what makes things unclear.
The pseudo-C signature in arrayProduct.c looks like this:
//pseudo C signature from arrayProduct.c
[void] arrayProduct([scalar], [matrix], [matrix], [scalar])
and a corresponding MATLAB function signature looks like this:
>> %pseudo MATLAB signature
>> [aMatrix] = arrayProduct([scalar], [matrix])
So the signatures are different :
C signature: no return value and four inputs
MATLAB signature: one return value and two inputs
I posted a diagram of MATLAB->MEX signature mapping as a comment on Walter's response below. I think this is what I was looking for.

请先登录,再进行评论。

类别

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