Matlab is a well-known data analysis and plotting program from Mathworks (ref. 1).
One of its strengths is that it can be extended to call user-written functions, via a facility known as MEX-files (ref. 2).
Essentially, a mex-file is a user function, written in C or Fortran, which has been compiled using a standard compiler, then
linked with special Matlab functions into a Windows DLL allowing the user function to be called from Matlab.
The Matlab functions provide the interface between Matlab and the user function, allowing parameters to be passed to the mex-file,
and the results passed back to Matlab.
Over the years researchers here at the Univ. of Wisconsin have collected a fair amount of Auditory Physiology data,
stored in a lab-standard format, and I have written a number
of Mex-files and functions as an aid for users who wish to import the data into Matlab for further analysis.
I named these functions "The Auditory Toolkit for Matlab", or AudMAT for short.
AudMAT functions are documented at http://www.neurophys.wisc.edu/comp/docs/audmat/ (ref. 3).
The problem
Recently it became necessary to modify and extend some of the AudMAT functions, but I ran into a problem.
When I issued the command to "make" the mex-file in Matlab, I got a fatal error, and no mex-file was created.
The error occurred even for files I had not changed in years.
To take the specific example of the mex-file named AudSpkTimes, the error was the following.
...
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
C:\DOCUME~1\kochhar\LOCALS~1\Temp\mex_6CC87F15-2BED-4775-5AA7-
F35B42C9DF90\audspktimes.obj
"c:\program files\audstuff\audsdk\daflib.lib" "c:\program files
\audstuff\audsdk\mislib.lib"
user32.lib advapi32.lib winspool.lib shell32.lib
LIBC.lib(malloc.obj) : error LNK2005: _malloc already defined
in MSVCRT.lib(MSVCRT.dll)
LIBC.lib(crt0init.obj) : error LNK2005: ___xc_z already defined
in MSVCRT.lib(cinitexe.obj)
LIBC.lib(crt0init.obj) : error LNK2005: ___xc_a already defined
in MSVCRT.lib(cinitexe.obj)
LIBC.lib(crt0init.obj) : error LNK2005: ___xi_z already defined
in MSVCRT.lib(cinitexe.obj)
LIBC.lib(crt0init.obj) : error LNK2005: ___xi_a already defined
in MSVCRT.lib(cinitexe.obj)
LIBC.lib(malloc.obj) : warning LNK4006: _malloc already defined
in MSVCRT.lib(MSVCRT.dll); second definition ignored
LIBC.lib(crt0init.obj) : warning LNK4006: ___xc_z already defined
in MSVCRT.lib(cinitexe.obj); second definition ignored
LIBC.lib(crt0init.obj) : warning LNK4006: ___xc_a already defined
in MSVCRT.lib(cinitexe.obj); second definition ignored
LIBC.lib(crt0init.obj) : warning LNK4006: ___xi_z already defined
in MSVCRT.lib(cinitexe.obj); second definition ignored
LIBC.lib(crt0init.obj) : warning LNK4006: ___xi_a already defined
in MSVCRT.lib(cinitexe.obj); second definition ignored
Creating library C:\DOCUME~1\kochhar\LOCALS~1\Temp\
mex_6CC87F15-2BED-4775-5AA7-F35B42C9DF90\templib.x
and object C:\DOCUME~1\kochhar\LOCALS~1\Temp\mex_6CC87F15-2BED-
4775-5AA7-F35B42C9DF90\templib.exp
LINK : warning LNK4098: defaultlib "MSVCRT" conflicts with use of
other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib "LIBC" conflicts with use of
other libs; use /NODEFAULTLIB:library
dfordll.lib(DFORMAIN.OBJ) : error LNK2001: unresolved external
symbol _MAIN__
audspktimes.mexw32 : fatal error LNK1120: 1 unresolved externals
C:\PROGRA~1\MATLAB\R2006B\BIN\MEX.PL: Error: Link of
'audspktimes.mexw32' failed.
??? Error using ==> mex
Unable to complete successfully.
Error in ==> makeAudSpkTimes at 1
mex -v audspktimes.cpp "c:\program files\audstuff\audsdk\daflib.lib"
"c:\program files\audstuff\audsdk\mislib.lib" user32.lib
advapi32.lib winspool.lib shell32.lib
>>
This was puzzling and disappointing.
I did not recall making any changes to any of the programs, but a few years had passed,
and possibly something had changed in the compilers or in Matlab itself, which was now a newer version.
As a first attempt, I tried to recompile the mex-file with the oldest version of Matlab I had, v6.5, but this resulted in the same error.
The solution
Taking a closer look, I noticed the error was on "line 1" in the file makeAudSpkTimes.m.
This is also the only line in that file, and contains the following:
mex -v audspktimes.cpp "c:\program files\audstuff\audsdk\daflib.lib"
"c:\program files\audstuff\audsdk\mislib.lib" user32.lib
advapi32.lib winspool.lib shell32.lib
This says, in effect, "compile audspiktimes.cpp and link it with the specified libraries and necessary mex functions".
Looking at the error message above, it appeared the problem was at the link stage.
In addition to the many warnings about functions already defined in LIBC.LIB, the fatal error was the following:
dfordll.lib(DFORMAIN.OBJ) : error LNK2001: unresolved external
symbol _MAIN__
audspktimes.mexw32 : fatal error LNK1120: 1 unresolved externals
This is an important clue. Dfordll.dll is the Fortran run-time library.
While audspktimes.cpp is written entirely in C/C++, the two libraries daflib.lib and mislib.lib contain functions in Fortran.
Specifically, Daflib functions are entirely in Fortran, while Mislib contains a mix of Fortran and C/C++ functions.
Could one of these libraries be to blame?
I noticed that only three functions were being called from Mislib.
As something to try, I copied those three functions to Daflib, recompiled daflib, and tried recompiling the mex-file again.
Suddenly, the compile worked in Matlab.
So, it seems the problem was something to do with Mislib, but what?
I did not want to abandon Mislib, because it contains dozens of functions used in many places.
I opened Mislib in Visual Studio v6 (this is what had been used to compile it always), and compared the project settings closely
with those for Daflib, paying particular attention to the Fortran compiler directives.
But I could find no differences.
Then I remembered that Mislib had some C++ functions, while Daflib had none, so I looked closely at the C++ compiler directives and options.
There was nothing here to compare directly with Daflib, but I noticed that the C/C++ compiler was using the Single Threaded run-time
library by default (see Fig. 1 below).