Compiling MEX on Win7 x64
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
I am attempting to compile some MEXes to run a demo of some vision science code. (https://github.com/bensapp/MODEC)
I'm running into compiler errors when doing so. I have MS Visual Studio 2010 linked as my C compiler, and I'm using MATLAB 2014a, 64bit, on Windows 7.
Error message:
features\resize.cc(36) : error C2057: expected constant expression
features\resize.cc(36) : error C2466: cannot allocate an array of constant size 0
features\resize.cc(36) : error C2133: 'ofs' : unknown size
features\resize.cc(70) : error C3861: 'bzero': identifier not found
features\resize.cc(95) : error C3861: 'round': identifier not found
features\resize.cc(96) : error C3861: 'round': identifier not found
C:\PROGRA~1\MATLAB\R2013B\BIN\MEX.PL: Error: Compile of 'features\resize.cc' failed.
if true
% code
end
Looking at other threads, it seems that some of the issue may be with a need to install the Windows SDK v7.1, but I cannot get that to install on my system correctly, from the web installer or the ISO download.
I'm attaching one of the modules I'm trying to compile, since it is short.
Advice on getting this working? Will getting Win SDK 7.1 installed likely solve the problem? Are there other 64bit compilers that may work better? Thanks in advance.
-John in Minnesota
-----resize.cc------------------------------
#include <math.h>
#include <assert.h>
#include <string.h>
#include "mex.h"
/*
* Fast image subsampling.
* This is used to construct the feature pyramid.
*/
// struct used for caching interpolation values
struct alphainfo {
int si, di;
double alpha;
};
// copy src into dst using pre-computed interpolation values
void alphacopy(double *src, double *dst, struct alphainfo *ofs, int n) {
struct alphainfo *end = ofs + n;
while (ofs != end) {
dst[ofs->di] += ofs->alpha * src[ofs->si];
ofs++;
}
}
// resize along each column
// result is transposed, so we can apply it twice for a complete resize
void resize1dtran(double *src, int sheight, double *dst, int dheight,
int width, int chan) {
double scale = (double)dheight/(double)sheight;
double invscale = (double)sheight/(double)dheight;
// we cache the interpolation values since they can be
// shared among different columns
int len = (int)ceil(dheight*invscale) + 2*dheight;
alphainfo ofs[len];
int k = 0;
for (int dy = 0; dy < dheight; dy++) {
double fsy1 = dy * invscale;
double fsy2 = fsy1 + invscale;
int sy1 = (int)ceil(fsy1);
int sy2 = (int)floor(fsy2);
if (sy1 - fsy1 > 1e-3) {
assert(k < len);
assert(sy-1 >= 0);
ofs[k].di = dy*width;
ofs[k].si = sy1-1;
ofs[k++].alpha = (sy1 - fsy1) * scale;
}
for (int sy = sy1; sy < sy2; sy++) {
assert(k < len);
assert(sy < sheight);
ofs[k].di = dy*width;
ofs[k].si = sy;
ofs[k++].alpha = scale;
}
if (fsy2 - sy2 > 1e-3) {
assert(k < len);
assert(sy2 < sheight);
ofs[k].di = dy*width;
ofs[k].si = sy2;
ofs[k++].alpha = (fsy2 - sy2) * scale;
}
}
// resize each column of each color channel
bzero(dst, chan*width*dheight*sizeof(double));
for (int c = 0; c < chan; c++) {
for (int x = 0; x < width; x++) {
double *s = src + c*width*sheight + x*sheight;
double *d = dst + c*width*dheight + x;
alphacopy(s, d, ofs, k);
}
}
}
// main function
// takes a double color image and a scaling factor
// returns resized image
mxArray *resize(const mxArray *mxsrc, const mxArray *mxscale) {
double *src = (double *)mxGetPr(mxsrc);
const int *sdims = mxGetDimensions(mxsrc);
if (mxGetNumberOfDimensions(mxsrc) != 3 ||
mxGetClassID(mxsrc) != mxDOUBLE_CLASS)
mexErrMsgTxt("Invalid input");
double scale = mxGetScalar(mxscale);
if (scale > 1)
mexErrMsgTxt("Invalid scaling factor");
int ddims[3];
ddims[0] = (int)round(sdims[0]*scale);
ddims[1] = (int)round(sdims[1]*scale);
ddims[2] = sdims[2];
mxArray *mxdst = mxCreateNumericArray(3, ddims, mxDOUBLE_CLASS, mxREAL);
double *dst = (double *)mxGetPr(mxdst);
double *tmp = (double *)mxCalloc(ddims[0]*sdims[1]*sdims[2], sizeof(double));
resize1dtran(src, sdims[0], tmp, ddims[0], sdims[1], sdims[2]);
resize1dtran(tmp, sdims[1], dst, ddims[1], ddims[0], sdims[2]);
mxFree(tmp);
return mxdst;
}
// matlab entry point
// dst = resize(src, scale)
// image should be color with double values
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
if (nrhs != 2)
mexErrMsgTxt("Wrong number of inputs");
if (nlhs != 1)
mexErrMsgTxt("Wrong number of outputs");
plhs[0] = resize(prhs[0], prhs[1]);
}
------------------------------
0 comentarios
Respuestas (2)
Geoff Hayes
el 2 de Oct. de 2014
John - I don't have a 64-bit PC (only 32-bit) so can't comment on whether using Win SDK 7.1 will solve the problem, or whether any other compiler will. I could compile the code on my Mac, and execute the resize function with out any issues.
An alternative to trying a different compiler, and this may work depending upon how many files you have and what the errors are for each, is that you try to correct them in the code.
The first error is concerned with the line
alphainfo ofs[len];
with error C2057 described as The context requires a constant expression, an expression whose value is known at compile time (see C2057). Since the code doesn't know len at runtime, you should be able to get around this with two lines of code that allocate and free memory. Replace the above with
alphainfo* ofs = (alphainfo*)mxCalloc(len,sizeof(alphainfo));
and then add the following as the last line in resize1dtran to free the memory allocated by the MATLAB memory manager
mxFree(ofs);
That should fix the first three errors that correspond to line 36.
The next error
error C3861: 'bzero': identifier not found
corresponds to the line
bzero(dst, chan*width*dheight*sizeof(double));
which is just initializing the dst array with all zeros. Replace this with memset
memset(dst,0,chan*width*dheight*sizeof(double));
As for the final two errors
error C3861: 'round': identifier not found
which correspond to the lines
ddims[0] = (int)round(sdims[0]*scale);
ddims[1] = (int)round(sdims[1]*scale);
You could create your own round function, adding it to resize.cc as
int round(double number)
{
return (number >= 0) ? (int)(number + 0.5) : (int)(number - 0.5);
}
I made the above changes and could compile the function without problems; running resize worked as expected. These are three relatively easy fixes, but if you have to make these changes over dozens of files (fixing errors that don't correspond to these three) could prove time consuming and slightly risky.
h612
el 20 de Sept. de 2015
I tried fixing these. got the Mex file successfully built. But now I've an error or invalid input error at
*Error using resize Invalid input
Error in featpyramid (line 28) scaled = resize(im, 1/sc^(i-1));*
1 comentario
Walter Roberson
el 20 de Sept. de 2015
That would happen if your im is not 3 dimensional. The code must be passed a color image.
Ver también
Categorías
Más información sobre MATLAB Compiler en Help Center y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!