float input data for mex not compiling the code

4 views (last 30 days)
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.

Accepted Answer

James Tursa
James Tursa on 10 Jun 2015
Edited: James Tursa on 10 Jun 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 Comments
James Tursa
James Tursa on 10 Jun 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:

Sign in to comment.

More Answers (0)

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!