Oba tytułowe błędy występują zawsze razem.
Żeby zrozumieć istotę tych błędów trzeba mniej więcej wiedzieć jak budowany jest kod wynikowy w C++. Musimy wiedzieć co robi preprocesor z plikami h, jak powstają obj, co zawierają, co to są biblioteki statyczne, co robi linker z plikami obj i bibliotekami statycznymi. Więcej tutaj:
I jeszcze o sygnaturach:
- Function Signatures
- Is the return type part of the function signature?
- What exactly is a function signature?
- Name mangling
- Microsoft Visual C++ Name Mangling
Poniższe przypadki odnoszą się do błędów związanych z symbolami w naszym kodzie, dalej są omówione przypadki błędów związanych z symbolami z bibliotek CRT i MFC.
Podwójna definicja symbolu (funkcja, zmienna)
Linker poszukuje eksportu symbolu dla powiązania go z jego importem i znajduje wiele eksportów o takiej samej syngaturze. Mogą się one znajdować w obj-tach, albo importowanych lib-ach. Po pierwsze możemy oznaczyć symbole używane tylko lokalnie w plikach
cpp
jako static, dzięki temu nie będą one eksportowane. Po drugie możemy zmienić nazwę spornych symboli. Deklaracja symbolu w pliku nagłówkowym
Problem pojawia się kiedy taki plik nagłówkowych zostanie dołączony do conajmniej dwóch różnych plików
cpp
. Rozwiązanie to pozostawienie deklaracji symbolu w pliku nagłówkowym i przeniesienie definicji do pliku cpp
. W przypadku funkcji możemy w ostateczności oznaczyć je jako inline
. Plik nagłówkowy dołączany jest wielokrotnie
Dopisz na początku pliku nagłówkowego
#pragma once
.Brak #include <afx.h>
Teraz załóżmy, że nasza solucja składa się z projektu pliku wykonywalnego i dołączanej do niej biblioteki statycznej z innego projektu w solucji. Taka przykładowa solucja jest używana dalej w artykule.
Opcje projektów
General|Character Set
są zgodne. Jeśli do projektu pliku wykonywalnego nie dołączymy afx.h
to dostaniemy błędy w zależności od Character Set
: 3>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)
3>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)
2>nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)
2>nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)
Błędów może być mniej albo więcej, zależy ile potencjalnie konfliktowych symboli użyliśmy. Oczywiście aby uzyskać takie błędy projekt pliku wykonywalnego nie może korzystać z MFC.
Niezgodność opcji projektów
Podejrzane opcje projektów to
General|Use of MFC
, General|Character Set
i C++|Code Generation|Runtime Library
. W zależności od ich kombinacji błędy będą różne. Oto niektóre podejrzane komunikaty:1>LINK : warning LNK4098: defaultlib 'nafxcwd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>msvcrtd.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj)
1>msvcrtd.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj)
1>LINK : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>LINK : warning LNK4098: defaultlib 'mfc100u.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>LINK : warning LNK4098: defaultlib 'mfcs100u.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>LINK : warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
Dla uniknięcia tego rodzaju błędów wspomniane wcześniej opcje powinny zostać ujednolicone.
Trochę więcej informacji na temat dwóch ostatnich przyapdków A LNK2005 error occurs when the CRT library and MFC libraries are linked in the wrong order in Visual C++
Brak komentarzy:
Prześlij komentarz