float input data for mex not compiling the code

i am trying to compile this code for mex file.. but getting errors with input data types..
void loopy( float ImgWeight[256][256],float ImgTemp[256][256],float PatchSetT[62001][64],float Row[125], float Col[125],float Ni,float I[249][249], float IWaveletMatrix[8][8], float WaveletMatrix[8][8], float DctMatrix[10][10] )
{
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
//DECLARING ALL THE ARGUMENTS
float *PatchSet; float *row; float *col; float Ni; float *I; float *IWM; float *WM; float *DM;
//float PRECISION CORRESPONDANCE OF THE OUTPUT
float *outMatrix;
float *outMatrix1;
int dims[2] = {256,256};
PatchSet = (float*)mxGetPr(prhs[0]);
row = (float*)mxGetPr(prhs[1]);
col = (float*)mxGetPr(prhs[2]);
I = (float*)mxGetPr(prhs[3]);
IWM = (float*)mxGetPr(prhs[4]);
WM = (float*)mxGetPr(prhs[5]);
DM = (float*)mxGetPr(prhs[6]);
Ni = (float)mxGetScalar(prhs[7]);
// SPECIAL CASE FOR ARRAYS
plhs[0] = mxCreateNumericArray(2,dims,mxSINGLE_CLASS,mxREAL);
plhs[1] = mxCreateNumericArray(2,dims,mxSINGLE_CLASS,mxREAL);
outMatrix = (float*)mxGetData(plhs[0]);
outMatrix1 = (float*)mxGetData(plhs[1]);
loopy(outMatrix,outMatrix,PatchSet,row,col,Ni,I,IWM,WM,DM);
}
The errors are ..
loopy.c(357) : warning C4047: 'function' : 'float (*)[256]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 1
loopy.c(357) : warning C4047: 'function' : 'float (*)[256]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 2
loopy.c(357) : warning C4047: 'function' : 'float (*)[64]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 3
loopy.c(357) : warning C4047: 'function' : 'float (*)[249]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 7
loopy.c(357) : warning C4047: 'function' : 'float (*)[8]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 8
loopy.c(357) : warning C4047: 'function' : 'float (*)[8]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 9
loopy.c(357) : warning C4047: 'function' : 'float (*)[10]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 10
C:\PROGRA~1\MATLAB\R2013A\BIN\MEX.PL: Error: Compile of 'loopy.c' failed.

 Réponse acceptée

James Tursa
James Tursa le 10 Juin 2015
Modifié(e) : James Tursa le 10 Juin 2015
If you insist on using the double bracket syntax [ ][ ] in your loopy function, then you need to realize that this is two levels of indirection, and the compiler will complain if the pointer types don't match up. In the warning messages, the compiler is telling you exactly what pointer types it expected. E.g.,
loopy.c(357) : warning C4047: 'function' : 'float (*)[256]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 1
loopy.c(357) : warning C4047: 'function' : 'float (*)[256]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 2
loopy.c(357) : warning C4047: 'function' : 'float (*)[64]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 3
loopy.c(357) : warning C4047: 'function' : 'float (*)[249]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 7
loopy.c(357) : warning C4047: 'function' : 'float (*)[8]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 8
loopy.c(357) : warning C4047: 'function' : 'float (*)[8]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 9
loopy.c(357) : warning C4047: 'function' : 'float (*)[10]' differs in levels of indirection from 'float *'
loopy.c(357) : warning C4024: 'loopy' : different types for formal and actual parameter 10
For ImgWeight, the type of the argument in the function signature is float (*)[256], or "pointer to an array of 256 floats". But you passed a variable of type float *, or "pointer to float". Those are different types of pointers with different levels of indirection, hence the compiler complaint. The fix is to give it the type of pointer it is expecting. Same for the other complaints. E.g.,
#include "mex.h"
void loopy( float ImgWeight[256][256],float ImgTemp[256][256],float PatchSetT[62001][64],float Row[125], float Col[125],float Ni,float I[249][249], float IWaveletMatrix[8][8], float WaveletMatrix[8][8], float DctMatrix[10][10] )
{
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
//DECLARING ALL THE ARGUMENTS
float (*PatchSet)[64]; // Type is "pointer to array of 64 floats"
float *row; float *col; // Type is "pointer to float"
float Ni; // Type is "float"
float (*I)[249]; // Type is "pointer to array of 249 floats"
float (*IWM)[8]; // Type is "pointer to array of 8 floats"
float (*WM)[8]; // Type is "pointer to array of 8 floats"
float (*DM)[10]; // Type is "pointer to array of 10 floats"
//float PRECISION CORRESPONDANCE OF THE OUTPUT
float (*outMatrix)[256]; // Type is "pointer to array of 256 floats"
float (*outMatrix1)[256]; // Type is "pointer to array of 256 floats"
int dims[2] = {256,256};
PatchSet = (float (*)[64]) mxGetData(prhs[0]);
row = (float *) mxGetData(prhs[1]);
col = (float *) mxGetData(prhs[2]);
I = (float (*)[249]) mxGetData(prhs[3]);
IWM = (float (*)[8]) mxGetData(prhs[4]);
WM = (float (*)[8]) mxGetData(prhs[5]);
DM = (float (*)[10]) mxGetData(prhs[6]);
Ni = (float) mxGetScalar(prhs[7]);
// SPECIAL CASE FOR ARRAYS
plhs[0] = mxCreateNumericArray(2,dims,mxSINGLE_CLASS,mxREAL);
plhs[1] = mxCreateNumericArray(2,dims,mxSINGLE_CLASS,mxREAL);
outMatrix = (float (*)[256]) mxGetData(plhs[0]);
outMatrix1 = (float (*)[256]) mxGetData(plhs[1]);
loopy(outMatrix,outMatrix,PatchSet,row,col,Ni,I,IWM,WM,DM);
}
Note the difference between the following:
float *PatchSet[64]; // Type is "array of 64 pointers to float"
float (*PatchSet)[64]; // Type is "pointer to array of 64 floats"
You need the parentheses because the brackets [ ] are higher precedence than the pointer *. To remember this rule you can use the following mnemonic:
Get a picture in your head of bowling. Imagine yourself in a bowling alley throwing a bowling ball down the lane to knock down some pins. There is a professional league of bowlers called the Professional Bowlers Association, or PBA. Say it out loud, "PBA", and have that picture of bowling in your head.
Now assign new words to the letters PBA:
Parentheses
Brackets
Asterisk
That is the order of precedence in the ( ), [ ], and * that you see in code. If you remember the picture of bowling in your head and remember the PBA, then you will never forget this precedence and will easily be able to decipher variable type definitions. E.g., take the example above:
float *PatchSet[64];
You've got an asterisk * and brackets [ ] present, so what type is the variable PatchSet? Remember PBA and you see that the brackets are higher precedence than the asterisk, so the first thing to apply to PatchSet is the brackets, meaning PatchSet is an "array ...". Finish up the brackets to get "array of 64 ...". Then once the brackets are deciphered the next thing present is the asterisk, so now we have "array of 64 pointers ...". And to finish it up the only thing left is the keyword float, so we end up with "array of 64 pointers to float".
Now examine the second example above:
float (*PatchSet)[64];
Here we have parentheses, so based on the PBA formula we must do whatever is inside the parentheses first. The only thing inside the parentheses in this case is an asterisk *, so we start with the type as "pointer to ...". There is nothing left inside the parentheses, so now move outside the parentheses and we see the brackets, so now we have "pointer to array ...". Finishing the brackets gives "pointer to array of 64 ...". And then apply the remaining keyword float to yield a final type of "pointer to array of 64 floats"
BIG CAVEAT: In function signatures, the first level of brackets [ ] for what you normally would think is an array is ALWAYS converted to (*) to get the type of an argument. So you need to apply this rule first before you determine type. Note that this is only for the arguments, not local variables. E.g., consider this code:
#include "mex.h"
void fun( int c[4][5], double d[6] ) // c is type "pointer to array of 5 ints"
// d is type "pointer to double"
{
int e[4][5]; // e is type "array of 4 arrays of 5 ints"
double f[6]; // f is type "array of 6 doubles"
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int a[4][5]; // a is type "array of 4 arrays of 5 ints"
double b[6]; // b is type "array of 6 doubles"
fun(a,b);
}
If you follow the PBA rule above you can probably decipher the types of a, b, e, and f easily. The types of c and d are special because they are function arguments, so apply the caveat "first level of [ ] is always converted to a pointer". The compiler actually sees that function signature as this:
void fun( int (*c)[5], double (*d) )
Once you understand this caveat you will understand the compiler messages you are seeing.
For the function call itself, note that whenever an array name is used in an expression, it is converted to a pointer. So for this call:
fun(a,b);
You might think that the types being passed are as follows based on the variable definitions:
fun( array of 4 arrays of 5 ints, array of 6 doubles );
But that is not the case. You used the variable name in an expression (the argument to a function call), so a conversion of the first level of brackets takes place first. The actual types being passed are:
fun( pointer to array of 5 ints, pointer to double );

7 commentaires

can you give me one relevant example of my case? I mean consider the Patch and guide me in that case..
James Tursa
James Tursa le 10 Juin 2015
Modifié(e) : James Tursa le 10 Juin 2015
I don't understand this request. I gave you code that has all of the pointer stuff corrected and annotated. Specifically what kind of example are you looking for?
how should I deal this "float *PatchSet; " in the above code.. I am a newbie..Half of your answer was 4 feet above my head. Just give me example of first input only please.
James Tursa
James Tursa le 10 Juin 2015
Modifié(e) : James Tursa le 10 Juin 2015
But I have already given this to you. The PatchSetT argument in the loopy function is as follows:
float PatchSetT[62001][64]
That means PatchSetT is of type "float (*)[64]", or "pointer to array of 64 floats". So in the calling routine you need to make sure that is the type of pointer you are passing. So this is what is used in my corrected code:
float (*PatchSet)[64];
Patchset is of type "float (*)[64]", or "pointer to array of 64 floats" ... exactly the type of pointer the function is expecting. To set its value there is this line:
PatchSet = (float (*)[64]) mxGetData(prhs[0]);
mxGetData returns the address of the first data element of prhs[0] as type "void *". We simply cast that "void *" to the type of PatchSet.
So now you can use the multi-level [ ][ ] syntax in your function as long as you realize the indexing will be backwards of MATLAB indexing (row-order vs column order).
"... Half of your answer was 4 feet above my head ..."
Not surprising. But based on your history of posts recently it was apparent that you do not understand multiple levels of indirection and how it relates to arrays etc. Rather than continuing to post corrections without in depth explanations, I thought it was time to post a tutorial of sorts. To solve your immediate problem you can just use my corrected code. To solve your future problems, I would suggest you study my tutorial at length over a period of several days or even weeks until you get a better grasp of what is going on. Pointers are hard enough to deal with properly ... multi-level pointers can be significantly more difficult and you will continue to have problems until you can grasp what I have written.
If you continue to have problems then by all means keep posting and I will help as I can. But I would advise bookmarking this thread and re-reading my tutorial several times over the next few weeks.
I understood you malloc concept very easily.. For sure I'll read this again and again till i get a proper idea.. Thanks for your help ..
James Tursa
James Tursa le 10 Juin 2015
Yes, just be clear that there are two different mechanisms. The one in this post assumes pointers to FIXED size arrays. You can't get the [ ][ ] syntax to work like you do in the above code unless the compiler knows the sizes of the arrays being pointed to at compile time. The compiler doesn't need to know the size inside the first level bracket [ ] ... in fact it ignores this value completely since it gets converted to (*). But it needs to know the sizes of the rest of the multi-level [ ] at compile time. You do know this in the above code, so this mechanism works.
But if you DON'T know the sizes at compile time and want to use the multi-level [ ][ ] syntax for dynamic sizes, then you are forced into something like the malloc approach I outlined in the other post:
Thanks James, You taught me a lot.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Performance and Memory dans Centre d'aide et File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by