MEX error LNK2019:unresolved symbol

25 ビュー (過去 30 日間)
Rachel Parise
Rachel Parise 2020 年 4 月 6 日
編集済み: James Tursa 2020 年 4 月 9 日
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?

回答 (2 件)

James Tursa
James Tursa 2020 年 4 月 9 日
編集済み: James Tursa 2020 年 4 月 9 日
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 2020 年 4 月 9 日
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:

カテゴリ

Help Center および File ExchangeWrite C Functions Callable from MATLAB (MEX Files) についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by