Hi
I have a project that generates an EXE which uses MFC, and also links in static libraries that use STL. During the link phase, I get the following errors:
GIPSSipVoiceEngine error LNK2005: "void * __cdecl operator new(unsigned int)" ( 2@YAPAXI@Z) already defined in GIPSSipVoiceEngineDll_debug.lib(AppDialogSet.obj)
GIPSSipVoiceEngine error LNK2005: "void __cdecl operator delete(void *,int,char const *,int)" ( 3@YAXPAXHPBDH@Z) already defined in GIPSSipVoiceEngineDll_debug.lib(AppDialogSet.obj)
I read a KB article(148652) that indicated that the C-Run time was being linked before the MFC libraries, and this needs to be reversed. So what I did was, as the KB article indicates, look inside AFX.h, and get the preprocessor macros between "#ifndef _AFX_NOFORCE_LIBS" and it's corresponding #endif, pasted that into the first header file included by AppDialogSet.cxx. However, the errors do not go away. The /verbose:lib output is below.
Linking...
Searching libraries
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\lib\winmm.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\lib\iphlpapi.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib\DelayImp.lib:
Searching \src\applications\sample_applications\sip\voice_engine_demo\dll\libraries\GIPSSipVoiceEngineDll_debug.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\lib\nafxcwd.lib:
nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" ( 2@YAPAXI@Z) already defined in GIPSSipVoiceEngineDll_debug.lib(AppDialogSet.obj)
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *,int,char const *,int)" ( 3@YAXPAXHPBDH@Z) already defined in GIPSSipVoiceEngineDll_debug.lib(AppDialogSet.obj)
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib\libcmtd.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib\kernel32.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\lib\user32.lib:
I'm also getting the following warning, if it's related. However, adding libcmt ot the list of libraries to be ignored gives me a whole host of other undefined symbol errors. Additionally, I thought this was the right one for a multithreaded project.
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
Thanks!
Neal

LNK2005 on new/delete
Fabio Gouw
Neal.
If linking your library to the main project causes these problems, why don't you just use the lib in the required classes.
by using #pragma comment("", lib) .
hope this helps solve your issue
AbhimanyuSirohi
Hi Holger
Thanks. I had tried adding the linker directives to the header file for the AppDialogSet.obj object file, as well a all header files that make up the LIB that AppDialogSet is part of, as well as all header files that make up other LIBS that this first lib depend on, and I've also double & triple checked the run-time settings to make sure that the code generation setting for the run time library agrees(/MTd). I've also gone further through the dependency chain and added the linker directives for all header files for those other libraries, too. Still no dice. I have a feeling that I am missing something obvious, but I can't for the life of me figure out what it might be.
That is an interesting tidbit about the .lib file being an indexed container. Out of curiousity, if you have a lib A that depends on another lib B, does A's output include an index to the .OBJ files for B, or does it refer to B to find the OBJ files that make B up at link time
Thanks
Neal
mirolslaw
Thank you for all your help. I have tried what you are saying, as well as a lot of other things this weekend, and I am still not able to get the duplicate new/delete errors to go away. I think I understand what you are saying, so I am unsure of why this does not work. Here is the linker command line:
/VERBOSE:LIB /OUT:"../executable/GIPSSoundWareDemo_debug.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:"..\..\..\..\..\resampler_48\main\libraries" /LIBPATH:"..\..\..\..\..\utility\main\libraries" /LIBPATH:"..\..\..\..\..\SRTP\main\source\Debug" /LIBPATH:"..\..\..\..\..\video_engine\engine\main\libraries" /LIBPATH:"..\..\..\..\..\voice_engine\engine\main\libraries" /NODEFAULTLIB:"libmmt.lib" /NODEFAULTLIB:"libircmt.lib" /NODEFAULTLIB:"libirc.lib" /NODEFAULTLIB:"libguide40.lib" /NODEFAULTLIB:"msvcrtd.lib" /DELAYLOAD:"OleAcc.dll" /DEBUG /PDB:".\Debug/GIPSSipVoiceEngineDemoGUI.pdb" /SUBSYSTEM:WINDOWS /MACHINE:X86 winmm.lib iphlpapi.lib srtplib.lib utility_debug.lib resampler48_debug.lib GIPSVoiceEngineLib_debug.lib GipsVideoEngineLib_debug.lib VideoEngineWindowsLib_debug.lib dssend.lib gipsreceive_debug.lib DelayImp.lib \src\applications\sample_applications\sip\voice_engine_demo\dll\libraries\GIPSSipVoiceEngineDll_debug.lib DelayImp.lib
The first library that includes directives is SRTPLIB.LIB. So I did "dumpbin /directives" on this library(very useful command btw), and saw that the directives inside did indeed refer to libcmtd.lib before nafxcwd.lib. So I went through every header file for SRPTLIB.LIB, added the #pragma commands for the linker to import nafxcwd before the C-runtime library, and recompiled it. Now, I can verify using the same dumpbin command that nafxcwd.lib always comes first in each "linker directives" section in the dumpbin output(does each section in the dumpbin output correspond to an object file, btw ). However, I am still getting the link error:
Searching \src\applications\sample_applications\sip\voice_engine_demo\dll\libraries\GIPSSipVoiceEngineDll_debug.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\lib\nafxcwd.lib:
nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" ( 2@YAPAXI@Z) already defined in GIPSSipVoiceEngineDll_debug.lib(AppDialogSet.obj)
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *,int,char const *,int)" ( 3@YAXPAXHPBDH@Z) already defined in GIPSSipVoiceEngineDll_debug.lib(AppDialogSet.obj)
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib\libcmtd.lib:
You can see the original search order of the libraries here:
------ Build started: Project: GIPSSipVoiceEngine, Configuration: Debug Win32 ------
Linking...
Searching libraries
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\lib\winmm.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\lib\iphlpapi.lib:
Searching ..\..\..\..\..\SRTP\main\source\Debug\srtplib.lib:
Searching ..\..\..\..\..\utility\main\libraries\utility_debug.lib:
Searching ..\..\..\..\..\resampler_48\main\libraries\resampler48_debug.lib:
Searching ..\..\..\..\..\voice_engine\engine\main\libraries\GIPSVoiceEngineLib_debug.lib:
Searching ..\..\..\..\..\video_engine\engine\main\libraries\GipsVideoEngineLib_debug.lib:
Searching ..\..\..\..\..\video_engine\engine\main\libraries\VideoEngineWindowsLib_debug.lib:
Searching ..\..\..\..\..\video_engine\engine\main\libraries\dssend.lib:
Searching ..\..\..\..\..\video_engine\engine\main\libraries\gipsreceive_debug.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib\DelayImp.lib:
Searching \src\applications\sample_applications\sip\voice_engine_demo\dll\libraries\GIPSSipVoiceEngineDll_debug.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\lib\nafxcwd.lib:
nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" ( 2@YAPAXI@Z) already defined in GIPSSipVoiceEngineDll_debug.lib(AppDialogSet.obj)
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *,int,char const *,int)" ( 3@YAXPAXHPBDH@Z) already defined in GIPSSipVoiceEngineDll_debug.lib(AppDialogSet.obj)
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib\libcmtd.lib:
Searching C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib\kernel32.lib:
Thank you again for all your help; I feel like I'm missing something extremely obvious!
Neal
sajithpt
Apparently, you have defined operator new/delete in AppDialogSet.cpp (or whatever is used to build AppDialogSet.obj). I would preprocess it and see where the definition comes from. You can't mix MFC new/delete debugging with custom operator new/delete. Maybe it's included due to incompatible preprocessor definitions.
-hg
Brian86
You should link all contributing compilands with the same runtime library model (/MT
or /MD
). Since a .lib file is only an indexed container for object files your static libraries need to built with the same options, too (that means you can't use /MTd for your static library /MT for your EXE).
Same thing for the link order. You need to include the header file with the _AFX_NOFORCE_LIBS stuff in your static library, too. The diagnostic tells you that AppDialogSets.obj already defines operator new.
-hg
Hanumanth Reddy
So here's the somewhat longer story on how things are supposed to work. There are four different runtime library options for VC++ /MD,/MT,/MDd and /MTd. When you compile a source file with these you will get a ".drectve" section in your object file with the corresponding /DEFAULTLIB switch (you can take a look at these with dumpbin /DIRECTIVES). This is also what you get with #pragma comment(linker/lib)
Now when you create a .lib from object files, the librarian puts all files in the archive and generates a symbol table which maps publicly visible symbols of the individual object files. No linking is done at that stage. You can't easily include a library into another. You would use #pragma comment(lib) to achieve a similar effect.
Only when you link things together (that's the final stage in your .EXE project) will symbols be resolved. First all object files directly specified at the command line are processed. During this processing ".drectve" things are parsed and undefined references to external are tracked. If there are unsatisfied references the linker will look at the symbol table of the static libraries. If it contains an entry for that symbol the linker extracts the corresponding object file and processes it. This process continues until all references are satisfied. You can take a look at how this works by adding /VERBOSE to the linker command line.
The C++ standard requires some of the operator new and delete forms to be replacable. Most implementations including VC++ do so by adding these operators in object files with no other public symbols. If you supply your own implementation in one of your source files the linker will never select these objects from the library because the corresponding symbol is already defined.
Now for your case it is a bit more complicated because the specialized implementations of operator new/delete are also in .lib files. Therefore you need to make sure that the MFC library /DEFAULTLIB switch is processed before the runtime library /DEFAULTLIB switch.
Do you still get the warning At least that one should be fairly easy to resolve. For the other I'd take a look at dumpbin /DIRECTIVES for the first object file that is supplied at the linker command line. You should see the afx library before the libcmt library switch.
-hg