Sdílet prostřednictvím


Chyba linkerů LNK2005

symbol již definovaný v objektu

Symbol symbolu byl definován více než jednou.

Za touto chybou následuje závažná chyba LNK1169.

Možné příčiny a řešení

Tato chyba obecně znamená, že jste přerušili jedno pravidlo definice, které umožňuje pouze jednu definici pro jakoukoli použitou šablonu, funkci, typ nebo objekt v daném souboru objektu a pouze jednu definici v celém spustitelném souboru pro externě viditelné objekty nebo funkce.

Tady je několik běžných příčin této chyby.

  • K této chybě může dojít, když soubor záhlaví definuje proměnnou. Pokud například tento soubor záhlaví zahrnete do více než jednoho zdrojového souboru v projektu, dojde k chybě:

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Mezi možná řešení patří:

    • Deklarujte proměnnou extern v souboru hlavičky: extern int global_int;a definujte ji a volitelně ji inicializujete v jednom a pouze jednom zdrojovém souboru: int global_int = 17;. Tato proměnná je nyní globální, kterou můžete použít v libovolném zdrojovém souboru tím, že ji externdeklarujete, například zahrnutím souboru hlavičky. Toto řešení doporučujeme pro proměnné, které musí být globální, ale dobrý postup softwarového inženýrství minimalizuje globální proměnné.

    • Deklarujte statickou proměnnou: static int static_int = 17;. Tím se omezí rozsah definice na aktuální soubor objektu a umožníte více souborům objektů mít vlastní kopii proměnné. Nedoporučujeme definovat statické proměnné v souborech hlaviček kvůli možnému nejasnostem s globálními proměnnými. Raději přesuňte definice statických proměnných do zdrojových souborů, které je používají.

    • Deklarujte proměnnou selectany: __declspec(selectany) int global_int = 17;. To říká linkeru, aby vybral jednu definici pro použití všemi externími odkazy a aby zbytek zahodil. Toto řešení je někdy užitečné při kombinování knihoven importu. Jinak ho nedoporučujeme jako způsob, jak se vyhnout chybám linkeru.

  • K této chybě může dojít, když soubor záhlaví definuje funkci, která není inline. Pokud tento hlavičkový soubor zahrnete do více než jednoho zdrojového souboru, získáte ve spustitelném souboru několik definic funkce.

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

    Mezi možná řešení patří:

    • inline Přidejte klíčové slovo do funkce:

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • Odeberte tělo funkce ze souboru záhlaví a ponechte pouze deklaraci, pak funkci implementujte v jednom a pouze jednom zdrojovém souboru:

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • K této chybě může dojít také v případě, že definujete členské funkce mimo deklaraci třídy v souboru hlaviček:

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

    Pokud chcete tento problém vyřešit, přesuňte definice členské funkce uvnitř třídy. Členské funkce definované uvnitř deklarace třídy jsou implicitně vloženy.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • K této chybě může dojít, pokud propojit více než jednu verzi standardní knihovny nebo CRT. Pokud se například pokusíte propojit maloobchodní i ladicí knihovny CRT nebo statické i dynamické verze knihovny nebo dvě různé verze standardní knihovny se spustitelným souborem, může se tato chyba hlásit mnohokrát. Pokud chcete tento problém vyřešit, odeberte všechny kromě jedné kopie každé knihovny z příkazu odkazu. Nedoporučujeme kombinovat maloobchodní a ladicí knihovny nebo různé verze knihovny ve stejném spustitelném souboru.

    Pokud chcete, aby linker používal jiné knihovny než výchozí hodnoty, na příkazovém řádku zadejte knihovny, které se mají použít, a pomocí možnosti /NODEFAULTLIB zakažte výchozí knihovny. V integrovaném vývojovém prostředí (IDE) přidejte odkazy na projekt, abyste určili knihovny, které se mají použít, a pak otevřete dialogové okno Stránky vlastností pro váš projekt a na stránce vlastností Linker, Input ( Vlastnost Linker), nastavte buď Ignorovat všechny výchozí knihovny, nebo ignorovat vlastnosti konkrétních výchozích knihoven, aby se zakázaly výchozí knihovny.

  • K této chybě může dojít v případě, že při použití možnosti /clr kombinujete použití statických a dynamických knihoven. K této chybě může dojít například v případě, že vytvoříte knihovnu DLL pro použití ve spustitelném souboru, který odkazuje ve statické CRT. Pokud chcete tento problém vyřešit, použijte pouze statické knihovny nebo pouze dynamické knihovny pro celý spustitelný soubor a všechny knihovny, které sestavíte, aby se používaly ve spustitelném souboru.

  • K této chybě může dojít, pokud je symbol zabalenou funkcí (vytvořenou kompilací pomocí /Gy) a byl součástí více než jednoho souboru, ale byl změněn mezi kompilacemi. Chcete-li tento problém vyřešit, překompilujte všechny soubory, které obsahují zabalenou funkci.

  • K této chybě může dojít, pokud je symbol definován odlišně ve dvou členských objektech v různých knihovnách a oba členské objekty se používají. Jedním ze způsobů, jak tento problém vyřešit, když jsou knihovny staticky propojené, je použít členský objekt pouze z jedné knihovny a zahrnout tuto knihovnu jako první do příkazového řádku linkeru. Pokud chcete použít oba symboly, musíte vytvořit způsob, jak je odlišit. Pokud například můžete sestavit knihovny ze zdroje, můžete každou knihovnu zabalit do jedinečného oboru názvů. Alternativně můžete vytvořit novou obálkovou knihovnu, která používá jedinečné názvy k zabalení odkazů na jednu z původních knihoven, propojit novou knihovnu s původní knihovnou a pak propojit spustitelný soubor s novou knihovnou místo původní knihovny.

  • K této chybě může dojít, pokud extern const je proměnná definována dvakrát a má v každé definici jinou hodnotu. Chcete-li tento problém vyřešit, definujte konstantu pouze jednou nebo použijte obory názvů nebo enum class definice k rozlišení konstant.

  • K této chybě může dojít, pokud používáte uuid.lib v kombinaci s jinými soubory .lib, které definují identifikátory GUID (například oledb.lib a adsiid.lib). Příklad:

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

    Pokud chcete tento problém vyřešit, přidejte /FORCE:MULTIPLE do možností příkazového řádku linkeru a ujistěte se, že uuid.lib je první odkazovaná knihovna.