Data from MEX-File to MATLAB
Mostrar comentarios más antiguos
Hi folks!
Suppose I want to find all divisors of an input to a MEX-File and return them to the user within MATLAB.
I have written the following simple program (I know it is not the most efficient implementation):
int i;
int counter = 0;
for(i=1;i <=input;i++){
if((input% i) == 0){
plhs[counter] = mxCreateDoubleScalar(i);
counter++;
}
}
Unfortunately, this does not seem to work. What am I doing wrong? What do I need to do to add multiple scalars to the output and why?
Thanks a lot, Jay
3 comentarios
James Tursa
el 6 de Jul. de 2011
What are you trying to do? Your code will return *input* number of variables, rather than a single variable with *input* number of elements. And it will only work if the calling routine requested *input* number of outputs. Is that what you want?
Jan
el 6 de Jul. de 2011
Please explain, what "this does not seem to work" means. Does it only seem, that it does not work, but it works? What results do you get? How do you call the function? How many outputs do you try to export?
Jay
el 6 de Jul. de 2011
Respuesta aceptada
Más respuestas (2)
James Tursa
el 6 de Jul. de 2011
The prhs[ ] is an array of input variables, and plhs[ ] is an array of output variables. MATLAB will allocate a fixed number of them based on the calling sequence. You can't go over that amount in your C code. e.g., for the calling sequence on the MATLAB side:
[A B C] = mymexfunction(X,Y)
you will get a prhs array that has been allocated to contain exactly two variables. prhs[0] will be the X input and prhs[1] will be the Y input. The nrhs will tell you how many inputs were on the function call on the MATLAB side, 2 in this case. Likewise, the plhs array will have been allocated to contain exactly three variables, which need to be filled in by you the programmer. So nlhs would be 3 and you would need to create plhs[0], plhs[1], and plhs[2] in your C code and then they would become A, B, and C once the mex functioins returns to MATLAB. In this loop that you show above:
for(i=1;i <=input;i++){
if((input%i) == 0){
plhs[counter] = mxCreateDoubleScalar(i);
counter++;
}
If you pass in a single value of 10 you would end up creating outputs for plhs[1], plhs[2], plhs[5], and plhs[10]. i.e., the user would have had to request 11 separate outputs for this to make sense (and even then you would not be setting 7 other outputs).
What you should be doing instead is creating a single output vector, plhs[0], then use mxGetPr on that to get a pointer to the data area, then use that to fill in values. The tricky part for you will be determining how large to make the output vector. This won't necessarily be easy for a large input value. If this is just a practice mex function you are writing then I would suggest doing something slightly different that has a size that is easy to calculate up front and then work that problem instead.
Jay
el 6 de Jul. de 2011
2 comentarios
Jay
el 6 de Jul. de 2011
James Tursa
el 6 de Jul. de 2011
Add this line at the end:
mxSetN(plhs[0],counter);
That will set the size to what you want, but of course the memory is still being used. This will not cause any problems in MATLAB that will crash, but it does use more memory than necessary. If you want to you could copy the data to a new smaller memory block. I would normally advise using mxRealloc in conjunction with mxGetPr and mxSetPr here, but mxRealloc has a bug for some versions of MATLAB and will not recover the memory. So you may need to do this manually via mxMalloc and memcpy.
Categorías
Más información sobre Startup and Shutdown en Centro de ayuda y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!