Bağlayıcı Araçları Hatası LNK2005

simgesi nesnede zaten tanımlanmış

Simge simgesi birden çok kez tanımlanmıştır.

Bu hatanın ardından önemli hata LNK1169.

Olası nedenler ve çözümler

Genel olarak bu hata, belirli bir nesne dosyasında kullanılan şablon, işlev, tür veya nesne için tek bir tanıma ve dışarıdan görünen nesneler veya işlevler için yürütülebilir dosyanın tamamında yalnızca bir tanıma izin veren tek tanım kuralını kırdığınız anlamına gelir.

Bu hatanın bazı yaygın nedenleri aşağıdadır.

  • Üst bilgi dosyası bir değişken tanımladığında bu hata oluşabilir. Örneğin, bu üst bilgi dosyasını projenize birden fazla kaynak dosyaya eklerseniz hata sonuçları:

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Olası çözümler şunları içerir:

    • Üst bilgi dosyasındaki değişkeni extern bildirin: extern int global_int;, ardından tanımlayın ve isteğe bağlı olarak tek ve tek bir kaynak dosyada başlatın: int global_int = 17;. Bu değişken artık herhangi bir kaynak dosyada, örneğin üst bilgi dosyasını ekleyerek bildirerek externkullanabileceğiniz bir genel değişkendir. Genel olması gereken değişkenler için bu çözümü öneririz, ancak iyi bir yazılım mühendisliği uygulaması genel değişkenleri en aza indirir.

    • Statik değişkenini bildirin: static int static_int = 17;. Bu, tanımın kapsamını geçerli nesne dosyasıyla kısıtlar ve birden çok nesne dosyasının değişkenin kendi kopyasına sahip olmasını sağlar. Genel değişkenlerle karışıklık olasılığı nedeniyle üst bilgi dosyalarında statik değişkenler tanımlamanızı önermiyoruz. Statik değişken tanımlarını bunları kullanan kaynak dosyalara taşımayı tercih edin.

    • selectany değişkenini bildirin: __declspec(selectany) int global_int = 17;. Bu, bağlayıcıya tüm dış başvurular tarafından kullanılmak üzere bir tanım seçmesini ve kalanları attırmalarını söyler. Bu çözüm bazen içeri aktarma kitaplıklarını birleştirirken yararlıdır. Aksi takdirde bağlayıcı hatalarından kaçınmanın bir yolu olarak bunu önermeyiz.

  • Bu hata, üst bilgi dosyası olmayan inlinebir işlev tanımladığında oluşabilir. Bu üst bilgi dosyasını birden fazla kaynak dosyaya eklerseniz yürütülebilir dosyada işlevin birden çok tanımını alırsınız.

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

    Olası çözümler şunları içerir:

    • anahtar sözcüğünü inline işleve ekleyin:

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • İşlev gövdesini üst bilgi dosyasından kaldırın ve yalnızca bildirimi bırakın, ardından işlevi tek ve tek bir kaynak dosyada uygulayın:

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • Bu hata, bir üst bilgi dosyasında sınıf bildirimi dışında üye işlevleri tanımlarsanız da oluşabilir:

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

    Bu sorunu düzeltmek için üye işlev tanımlarını sınıfının içine taşıyın. Sınıf bildirimi içinde tanımlanan üye işlevleri örtük olarak çizilidir.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • Bu hata, standart kitaplığın veya CRT'nin birden fazla sürümünü bağlarsanız oluşabilir. Örneğin, hem perakende hem de hata ayıklama CRT kitaplıklarını ya da bir kitaplığın hem statik hem de dinamik sürümlerini ya da standart kitaplığın iki farklı sürümünü yürütülebilir dosyanıza bağlamaya çalışırsanız, bu hata birçok kez bildirilebilir. Bu sorunu çözmek için, bağlantı komutundan her kitaplığın bir kopyası dışında tüm kopyalarını kaldırın. Aynı yürütülebilir dosyada perakende ve hata ayıklama kitaplıklarını veya kitaplığın farklı sürümlerini karıştırmanızı önermeyiz.

    Bağlayıcıya varsayılanlar dışındaki kitaplıkları kullanmasını söylemek için, komut satırında kullanılacak kitaplıkları belirtin ve /NODEFAULTLIB seçeneğini kullanarak varsayılan kitaplıkları devre dışı bırakın. IDE'de, kullanılacak kitaplıkları belirtmek için projenize başvurular ekleyin, sonra projenizin Özellik Sayfaları iletişim kutusunu açın ve Bağlayıcı, Giriş özellik sayfasında, varsayılan kitaplıkları devre dışı bırakmak için Tüm Varsayılan Kitaplıkları Yoksay veya Belirli Varsayılan Kitaplıkları Yoksay'ı ayarlayın.

  • Bu hata, /clr seçeneğini kullandığınızda statik ve dinamik kitaplıkların kullanımını karıştırırsanız oluşabilir. Örneğin, bu hata, statik CRT'ye bağlanan yürütülebilir dosyanızda kullanmak üzere bir DLL oluşturursanız oluşabilir. Bu sorunu çözmek için yalnızca statik kitaplıkları veya yalnızca yürütülebilir dosyanın tamamı ve yürütülebilir dosyada kullanmak üzere oluşturduğunuz tüm kitaplıklar için dinamik kitaplıkları kullanın.

  • Bu hata, simge paketlenmiş bir işlevse (/Gy ile derlenerek oluşturuldu) ve birden fazla dosyaya dahil edildiyse, ancak derlemeler arasında değiştirildiyse oluşabilir. Bu sorunu çözmek için paketlenmiş işlevi içeren tüm dosyaları yeniden derle.

  • Bu hata, simge farklı kitaplıklardaki iki üye nesnede farklı tanımlanmışsa ve her iki üye nesne de kullanılıyorsa oluşabilir. Kitaplıklar statik olarak bağlı olduğunda bu sorunu düzeltmenin bir yolu, üye nesnesini yalnızca bir kitaplıktan kullanmak ve önce bağlayıcı komut satırına bu kitaplığı eklemektir. Her iki simgeyi de kullanmak için bunları ayırt etmek için bir yol oluşturmanız gerekir. Örneğin, kitaplıkları kaynaktan derleyebilirseniz, her kitaplığı benzersiz bir ad alanına sarmalayabilirsiniz. Alternatif olarak, başvuruları özgün kitaplıklardan birine kaydırmak için benzersiz adlar kullanan yeni bir sarmalayıcı kitaplığı oluşturabilir, yeni kitaplığı özgün kitaplığa bağlayabilir ve sonra yürütülebilir dosyayı özgün kitaplık yerine yeni kitaplığınıza bağlayabilirsiniz.

  • Bir değişken iki kez tanımlanırsa ve her tanımda farklı bir değere sahipse extern const bu hata oluşabilir. Bu sorunu çözmek için sabiti yalnızca bir kez tanımlayın veya sabitleri ayırt etmek için ad alanlarını veya enum class tanımları kullanın.

  • Uuid.lib dosyasını GUID'leri tanımlayan diğer .lib dosyalarıyla (örneğin oledb.lib ve adsiid.lib) birlikte kullandığınızda bu hata oluşabilir. Örnek:

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

    Bu sorunu çözmek için bağlayıcı komut satırı seçeneklerine /FORCE:MULTIPLE ekleyin ve uuid.lib dosyasının başvuruda bulunılan ilk kitaplık olduğundan emin olun.