HELP....mxCallMATLAB output assignment to variable???
Mostrar comentarios más antiguos
I've spent a week on the following problem and I can't for the life of me figure it out! I'm going to be as brief as possible with the code and chop out irrelevant lines but it should be clear as to my problem. For starters, I'm using Matlab in combination with C, which communicates via mex files. Without further ado...
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
static double *U
plhs[4] = mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL);
U = (double*)mxGetPr(plhs[4]);
/* C code which solves for "U" based on a number of other input variables*/
solve(U,...,...,...)
/* C code which solves for "U" based on a number of other input variables*/
derivative(U,...,...,...)
}
After execution, everything works fine and I have the value for the derivative of "U". I then wanted to compare solvers so I'm swapping out the "solve(U)" for a Matlab function which I call via "mexCallMATLAB". Here is where I get lost
(Again I removed irrelevant variables)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
static double *U
plhs[4] = mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL);
U = (double*)mxGetPr(plhs[4]);
/* Call MATLAB solver */
mxArray *Uin[8],*Uout[2];
Uin[0] = mxCreateNumericArray(2,dims,mxSINGLE_CLASS,mxREAL);
memcpy(mxGetPr(Uin[0]),(some variable),m*n*sizeof(float));
yes there are 8 inputs...I just removed for simplicity
mexCallMATLAB(2,Uout,8,Uin,"my_matlab_solver");
I then check the results of "Uout" with the following:
mexCallMATLAB(0,NULL,1,&Uout[0],"plot_variable");
Everything works out great, but the "C" code that later calls on the variable "U" to find it's derivative does not work.
plhs[4] = Uout[0];
/* C code which solves for "U" based on a number of other input variables*/
derivative(U,...,...,...)
}
I can not figure out how to assign "Uout[0]" to "U". I thought by setting plhs[4] = Uout[0] then U would point to the results from "my_matlab_solver" but it does not. There are no compile errors.
Is there easier way where I can assign the output of "my_matlab_solver" directly to "U" with out having to make a mxArray for the output? This whole MEX thing seems a lot more complicated than it needs to be. Thanks for you help!
************************************************************************** ************************************************************************** **************************************************************************
EDIT: I'm going to be very blunt
I have a variable called "U" which is defined as follows
U = (double*)mxGetPr(plhs[4]);
How do I assign the output from this mexCallMATLAB
mexCallMATLAB(2,Uout,8,Uin,"my_matlab_solver");
to "U"? I tried this; plhs[4] = Uout[0]; but it does not work. Don't worry about the rest of the code it's fine. My problem is strictly related to assigning the output of mexCallMATLAB to a variable defined as "U" is above.
5 comentarios
James Tursa
el 23 de Mayo de 2013
Editada: James Tursa
el 23 de Mayo de 2013
In this line:
memcpy(mxGetPr(Uin[0]),(some variable),m*n*sizeof(float));
Either you need sizeof(double) if (some variable) is a double, or you need to recode this in a loop and manually assign each element if (some variable) is a float.
With regards to your other questions, I think we will need to see more of your code, and get a more detailed description of "does not work".
HiWave
el 23 de Mayo de 2013
James Tursa
el 24 de Mayo de 2013
Yep ... I was mislead by the mxGetPr (returns a double *) and failed to notice the mxSINGLE_CLASS in the construction.
Jan
el 25 de Mayo de 2013
You cannot and should assign the output of the Matlab call to U. The output of the Matlab call is an mxArray variable and U is a pointer to a double array. Perhaps you want to obtain another pointer to the data of the output.
It seems, like the concept of the mxArray variables and the pointers to their contents is not clear to you already.
It is hard for me to give advices of the code, because the code is posted in parts and distributed over several comments and sections. I do not think that the rest of the code is fine, because the confusion with the mxArray plhs[4] and pointers to data appear repeatedly.
Respuesta aceptada
Más respuestas (2)
James Tursa
el 24 de Mayo de 2013
Editada: James Tursa
el 24 de Mayo de 2013
Your words from above:
EDIT: I'm going to be very blunt
I have a variable called "U" which is defined as follows
U = (double*)mxGetPr(plhs[4]);
How do I assign the output from this mexCallMATLAB
mexCallMATLAB(2,Uout,8,Uin,"my_matlab_solver");
to "U"? I tried this;
plhs[4] = Uout[0];
but it does not work. Don't worry about the rest of the code it's fine. My problem is strictly related to assigning the output of mexCallMATLAB to a variable defined as "U" is above.
-----------------------------------------------------------------------------
If Uout[0] is indeed assigned by the mexCallMATLAB call, then the plhs[4] = Uout[0] line should have worked, assuming that you do the U = mxGetPr(plhs[4]) line after assigning plhs[4]. In orher words, this order should work:
mexCallMATLAB(2,Uout,8,Uin,"my_matlab_solver");
plhs[4] = Uout[0];
U = mxGetPr(plhs[4]);
And, as Jan has already pointed out, you need to delete a couple of lines related to your first plhs[4] = etc to avoid a memory leak.
5 comentarios
James Tursa
el 25 de Mayo de 2013
Please show all of the code showing how each variable is declared and how the values are set. We have no way of knowing in your code snippets above how plhs[4] is set or how U is set, for instance. How do I know if the memcpy is right or wrong if I don't see what U points to? I would request that you post the entire code section that works for you, and also post the entire code section that does not work. Then we can comment. Getting stuff to plot via mexCallMATLAB should not be this hard.
HiWave
el 25 de Mayo de 2013
HiWave
el 25 de Mayo de 2013
James Tursa
el 26 de Mayo de 2013
The difference between the two above is as follows:
> V = mxGetPr(plhs[1]);
This gets the data pointer from the mxArray plhs[1], which must have a valid mxArray in it or the routine will probably crash MATLAB. This data pointer value is assigned to the variable V. I.e., this statement is just a pointer value assignment to a variable. The data itself is not examined or copied.
> memcpy(mxGetPr(APPLE[0]),V,5*10*sizeof(double));
This copies 50 double values from V into the data memory of the mxArray APPLE[0]. V must point to valid double memory of at least 50 elements and APPLE[0] must already be created to have at least 50 double elements of data or MATLAB will crash.
> APPLE[0] = plhs[1];
This copies the pointer value of plhs[1] into the pointer value of APPLE[0]. It doesn't do anything more. Nothing is checked, no attempt is made to examine the underlying mxArray, and no data is examined or copied. The statement is simply the assignment of a pointer value to a variable.
Jan
el 23 de Mayo de 2013
I do not understand, what you want to achieve:
plhs[4] = mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL);
U = (double*)mxGetPr(plhs[4]);
Now U is the pointer to the data of the 5th output argument.
plhs[4] = Uout[0];
Now the 5th output is overwritten, which means a memory leak (which is caught automatically when the mex function is left fortunately).
But what does >>assign "Uout[0]" to "U"<< mean now? Do you want to get the pointer to the data of Uout[0] again?
U = mxGetPr(Uout[0]);
Btw., mxGetPr replies a double * already, such that you do not have to cast it.
Categorías
Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!