MEX error LNK2019:unresolved symbol

13 views (last 30 days)
Rachel Parise
Rachel Parise on 6 Apr 2020
Edited: James Tursa on 9 Apr 2020
Getting this error and I cannot figure out why,
Determining peak list...
Creating summarisation matrices...
Building with 'Microsoft Windows SDK 7.1 (C)'.
Error using mex
Creating library symmeig.lib and object symmeig.exp
symmeig.obj : error LNK2019: unresolved external symbol mxGetDoubles
referenced in function mexFunction
symmeig.mexw64 : fatal error LNK1120: 1 unresolved externals
Error in memoryEfficientPCA (line 169)
mex('-largeArrayDims', 'symmeig.c', lapacklib)
Here is the text where the error arises:
% Attempt to update Q using the mex file update
try
Q = updateQ(Q, counts(indicesList));
catch exception
% Failed to call updateQ so compile all functions if a compiler
% is installed on the system
compiler = mex.getCompilerConfigurations().Manufacturer;
if(strcmp(compiler, 'LCC'))
folder = 'lcc';
elseif(strcmp(compiler, 'Microsoft'))
folder = 'Microsoft';
else
error('No compiler selected?');
end
lapacklib = fullfile(matlabroot, 'extern', 'lib', 'win64', 'microsoft', 'libmwlapack.lib');
mex ('-largeArrayDims', 'symmeig.c', lapacklib)
mex('-largeArrayDims', 'updateQ.c')
mex('-largeArrayDims', 'calculateE.c')
And the code associated wtih symmeig.c
#include "mex.h"
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray*prhs[] )
double *AP, *D, *E, *tau, *Q, *work;
int n, info;
char buffer[256];
/* Create the vectors required as output and intermediate variables */
mxArray *DArray, *EArray, *TAUArray, *QArray, *workArray;
if (nrhs!=2)
mexErrMsgTxt("Must have exactly two input arguments.");
if (nlhs>2)
mexErrMsgTxt("Too many output arguments.");
if (!mxIsDouble(prhs[0]) || !mxIsDouble(prhs[1]))
mexErrMsgTxt("Both inputs must be double arrays.");
if (mxIsComplex(prhs[0]) || mxIsComplex(prhs[1]))
mexErrMsgTxt("Both inputs must be real.");
if (mxGetM(prhs[0])!=1 && mxGetN(prhs[0])!=1)
mexErrMsgTxt("First input must be a vector.");
if (mxGetM(prhs[1]) == 1 && mxGetN(prhs[1]) == 0)
mexErrMsgTxt("Second input must be a scalar.");
/* */
n = mxGetPr(prhs[1])[0];
if(mxGetNumberOfElements(prhs[0]) != (n*(n+1)/2))
mexErrMsgTxt("The vector is the wrong size for the N specified");
DArray = mxCreateDoubleMatrix(n, 1, mxREAL);
EArray = mxCreateDoubleMatrix(n-1, 1, mxREAL);
TAUArray = mxCreateDoubleMatrix(n-1, 1, mxREAL);
QArray = mxCreateDoubleMatrix(n, n, mxREAL);
workArray = mxCreateDoubleMatrix(2*n-2, 1, mxREAL);
D = mxGetDoubles(DArray);
E = mxGetDoubles(EArray);
tau = mxGetDoubles(TAUArray);
Q = mxGetDoubles(QArray);
work = mxGetDoubles(workArray);
/* Return D (eigenvalues) and Q (eigenvectors) */
plhs[0] = DArray;
plhs[1] = QArray;
/* Assign the input vector to AP */
AP = mxGetPr(prhs[0]);
/* Reduce symmetric matrix to tridiagonal form */
#if defined _WIN32 || defined _WIN64
dsptrd("U", &n, AP, D, E, tau, &info);
#else
dsptrd_("U", &n, AP, D, E, tau, &info);
#endif
if (info < 0) {
sprintf(buffer, "Error using DSPTRD with input: %d", -1*info);
/* Cleanup */
mxDestroyArray(TAUArray);
mxDestroyArray(EArray);
mxDestroyArray(workArray);
mexErrMsgTxt(buffer);
}
/* Generate orthogonal matrix Q */
#if defined _WIN32 || defined _WIN64
dopgtr("U", &n, AP, tau, Q, &n, work, &info);
#else
dopgtr_("U", &n, AP, tau, Q, &n, work, &info);
#endif
/* Free up the unneeded vector */
mxDestroyArray(TAUArray);
if (info < 0) {
sprintf(buffer, "Error using DOPGTR with input: %d", -1*info);
/* Cleanup */
mxDestroyArray(EArray);
mxDestroyArray(workArray);
mexErrMsgTxt(buffer);
}
/* Compute all eigenvalues and eigenvectors using implicit QL or QR method. */
#if defined _WIN32 || defined _WIN64
dsteqr("V", &n, D, E, Q, &n, work, &info);
#else
dsteqr_("V", &n, D, E, Q, &n, work, &info);
#endif
/* Free up unneeded vectors */
mxDestroyArray(EArray);
mxDestroyArray(workArray);
if (info < 0) {
sprintf(buffer, "Error using DSTEQR with input: %d", -1*info);
mexErrMsgTxt(buffer);
} else if(info > 0) {
sprintf(buffer, "Error using DSTEQR: failed to find all eigenvalues in a total of %d iterations. %d elements of E have not converged to zero.", 30*n, info);
mexErrMsgTxt(buffer);
What does this error mean and how do I resolve?

Answers (2)

James Tursa
James Tursa on 9 Apr 2020
Edited: James Tursa on 9 Apr 2020
mxGetDoubles( ) is a new API routine that only exists in the R2018a+ API memory model. You have to compile with the -R2018a flag. E.g.,
mex('-R2018a', 'symmeig.c', lapacklib)
You may also run into problems with these definitions:
int n, info;
For 64-bit code the BLAS and LAPACK libraries probably use 64-bit integers, but int is likely only a 32-bit integer. To be safe, always use mwSignedIndex when using integers that are passed into BLAS or LAPACK library routines. E.g.,
mwSignedIndex n, info;
And this check
if (nlhs>2)
mexErrMsgTxt("Too many output arguments.");
should be this instead
if (nlhs != 2)
mexErrMsgTxt("Need exactly two output arguments.");
otherwise this line can bomb MATLAB if less than two outputs are requested:
plhs[1] = QArray;

Harsha Priya Daggubati
Harsha Priya Daggubati on 9 Apr 2020
Hi,
The unresolved external symbols errors indicate that during the link-stage of compiling the MEX-file, these symbols are not available.
Your error points that mxGetDoubles is undefined, which is a basic function available. Can you try building the shipped 'explore.c' file and let me know if the same error pops-up.
Refer to the following link:

Categories

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

Community Treasure Hunt

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

Start Hunting!