Błąd narzędzi konsolidatora LNK2005

symbol już zdefiniowany w obiekcie

Symbol symbolu został zdefiniowany więcej niż raz.

Po tym błędzie występuje błąd krytyczny LNK1169.

Możliwe przyczyny i rozwiązania

Ogólnie rzecz biorąc, ten błąd oznacza, że jedna reguła definicji, która zezwala tylko na jedną definicję dla dowolnego używanego szablonu, funkcji, typu lub obiektu w danym pliku obiektu i tylko jedną definicję w całym pliku wykonywalnym dla obiektów lub funkcji widocznych zewnętrznie.

Poniżej przedstawiono niektóre typowe przyczyny tego błędu.

  • Ten błąd może wystąpić, gdy plik nagłówka definiuje zmienną. Jeśli na przykład ten plik nagłówkowy zostanie uwzględniny w więcej niż jednym pliku źródłowym w projekcie, zostanie wyświetlony błąd:

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Możliwe rozwiązania są następujące:

    • Zadeklaruj zmienną extern w pliku nagłówka: extern int global_int;, a następnie zdefiniuj ją i opcjonalnie zainicjuj w jednym i tylko jednym pliku źródłowym: int global_int = 17;. Ta zmienna jest teraz globalna, której można użyć w dowolnym pliku źródłowym, deklarując ją externna przykład przez dołączenie pliku nagłówka. Zalecamy to rozwiązanie dla zmiennych, które muszą być globalne, ale dobra praktyka inżynieryjna oprogramowania minimalizuje zmienne globalne.

    • Zadeklaruj zmienną statyczną: static int static_int = 17;. Ogranicza to zakres definicji do bieżącego pliku obiektu i umożliwia wielu plikom obiektów posiadanie własnej kopii zmiennej. Nie zalecamy definiowania zmiennych statycznych w plikach nagłówków ze względu na potencjalne zamieszanie ze zmiennymi globalnymi. Preferuj przenoszenie definicji zmiennych statycznych do plików źródłowych, które ich używają.

    • Zadeklaruj zmienną selectany: __declspec(selectany) int global_int = 17;. Spowoduje to, że konsolidator wybierz jedną definicję do użycia przez wszystkie odwołania zewnętrzne i odrzuci resztę. To rozwiązanie jest czasami przydatne podczas łączenia bibliotek importu. W przeciwnym razie nie zalecamy go jako sposobu na uniknięcie błędów konsolidatora.

  • Ten błąd może wystąpić, gdy plik nagłówkowy definiuje funkcję, która nie inlinejest . Jeśli ten plik nagłówkowy zostanie uwzględniony w więcej niż jednym pliku źródłowym, uzyskasz wiele definicji funkcji w pliku wykonywalnego.

    // LNK2005_func.h
    int sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Możliwe rozwiązania są następujące:

    • inline Dodaj słowo kluczowe do funkcji:

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • Usuń treść funkcji z pliku nagłówka i pozostaw tylko deklarację, a następnie zaimplementuj funkcję w jednym i tylko jednym pliku źródłowym:

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • Ten błąd może wystąpić również w przypadku definiowania funkcji składowych poza deklaracją klasy w pliku nagłówka:

    // LNK2005_member_outside.h
    class Sample {
    public:
        int sample_function(int);
    };
    int Sample::sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Aby rozwiązać ten problem, przenieś definicje funkcji składowych wewnątrz klasy. Funkcje składowe zdefiniowane wewnątrz deklaracji klasy są niejawnie wbudowane.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • Ten błąd może wystąpić, jeśli łączysz więcej niż jedną wersję standardowej biblioteki lub narzędzia CRT. Jeśli na przykład spróbujesz połączyć biblioteki detaliczne i debugowania CRT albo statyczne i dynamiczne wersje biblioteki albo dwie różne wersje biblioteki standardowej do pliku wykonywalnego, ten błąd może zostać zgłoszony wiele razy. Aby rozwiązać ten problem, usuń jedną kopię każdej biblioteki z polecenia linku. Nie zalecamy łączenia bibliotek detalicznych i debugowania ani różnych wersji biblioteki w tym samym pliku wykonywalnym.

    Aby poinformować konsolidatora o używaniu bibliotek innych niż domyślne, w wierszu polecenia określ biblioteki do użycia i użyj opcji /NODEFAULTLIB , aby wyłączyć biblioteki domyślne. W środowisku IDE dodaj odwołania do projektu, aby określić biblioteki do użycia, a następnie otwórz okno dialogowe Strony właściwości dla projektu, a następnie na stronie konsolidatora właściwości Input ustaw opcję Ignoruj wszystkie biblioteki domyślne lub Ignoruj określone domyślne biblioteki, aby wyłączyć biblioteki domyślne.

  • Ten błąd może wystąpić, jeśli używasz bibliotek statycznych i dynamicznych podczas korzystania z opcji /clr . Na przykład ten błąd może wystąpić, jeśli skompilujesz bibliotekę DLL do użycia w pliku wykonywalnym, który łączy się ze statycznym plikiem CRT. Aby rozwiązać ten problem, użyj tylko bibliotek statycznych lub tylko bibliotek dynamicznych dla całego pliku wykonywalnego i wszystkich bibliotek utworzonych do użycia w pliku wykonywalnego.

  • Ten błąd może wystąpić, jeśli symbol jest funkcją spakowana (utworzoną przez kompilowanie z /Gy) i została uwzględniona w więcej niż jednym pliku, ale została zmieniona między kompilacjami. Aby rozwiązać ten problem, ponownie skompiluj wszystkie pliki, które zawierają spakowana funkcja.

  • Ten błąd może wystąpić, jeśli symbol jest zdefiniowany inaczej w dwóch obiektach członkowskich w różnych bibliotekach, a oba obiekty członkowskie są używane. Jednym ze sposobów rozwiązania tego problemu, gdy biblioteki są statycznie połączone, jest użycie obiektu członkowskiego tylko z jednej biblioteki i dołączenie tej biblioteki najpierw w wierszu polecenia konsolidatora. Aby użyć obu symboli, należy utworzyć sposób ich odróżnienia. Jeśli na przykład możesz skompilować biblioteki ze źródła, możesz opakowować każdą bibliotekę w unikatowej przestrzeni nazw. Alternatywnie możesz utworzyć nową bibliotekę otoki, która używa unikatowych nazw do zawijania odwołań do jednej z oryginalnych bibliotek, połączyć nową bibliotekę z oryginalną biblioteką, a następnie połączyć plik wykonywalny z nową biblioteką zamiast oryginalnej biblioteki.

  • Ten błąd może wystąpić, jeśli zmienna extern const jest definiowana dwukrotnie i ma inną wartość w każdej definicji. Aby rozwiązać ten problem, zdefiniuj stałą tylko raz lub użyj przestrzeni nazw lub enum class definicji, aby odróżnić stałe.

  • Ten błąd może wystąpić, jeśli używasz biblioteki uuid.lib w połączeniu z innymi plikami lib definiującymi identyfikatory GUID (na przykład oledb.lib i adsiid.lib). Przykład:

    oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject
    already defined in uuid.lib(go7.obj)
    

    Aby rozwiązać ten problem, dodaj /FORCE:MULTIPLE do opcji wiersza polecenia konsolidatora i upewnij się, że element uuid.lib jest pierwszą biblioteką, do którego odwołuje się biblioteka.