Bagikan melalui


LNK2005 Kesalahan Alat Linker

simbol sudah ditentukan dalam objek

Simbol simbol didefinisikan lebih dari sekali.

Kesalahan ini diikuti oleh kesalahan fatal LNK1169.

Kemungkinan penyebab dan solusi

Umumnya, kesalahan ini berarti Anda telah merusak satu aturan definisi, yang hanya memungkinkan satu definisi untuk templat, fungsi, jenis, atau objek yang digunakan dalam file objek tertentu, dan hanya satu definisi di seluruh yang dapat dieksekusi untuk objek atau fungsi yang terlihat secara eksternal.

Berikut adalah beberapa penyebab umum untuk kesalahan ini.

  • Kesalahan ini dapat terjadi ketika file header menentukan variabel. Misalnya, jika Anda menyertakan file header ini dalam lebih dari satu file sumber dalam proyek Anda, hasil kesalahan:

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Solusi yang mungkin meliputi:

    • Deklarasikan variabel extern dalam file header: extern int global_int;, lalu tentukan dan inisialisasi secara opsional dalam satu dan hanya satu file sumber: int global_int = 17;. Variabel ini sekarang merupakan global yang dapat Anda gunakan dalam file sumber apa pun dengan mendeklarasikannya extern, misalnya, dengan menyertakan file header. Kami merekomendasikan solusi ini untuk variabel yang harus global, tetapi praktik rekayasa perangkat lunak yang baik meminimalkan variabel global.

    • Deklarasikan variabel statis: static int static_int = 17;. Ini membatasi cakupan definisi ke file objek saat ini, dan memungkinkan beberapa file objek untuk memiliki salinan variabelnya sendiri. Kami tidak menyarankan Anda menentukan variabel statis dalam file header karena potensi kebingungan dengan variabel global. Lebih suka memindahkan definisi variabel statis ke dalam file sumber yang menggunakannya.

    • Deklarasikan variabel selectany: __declspec(selectany) int global_int = 17;. Ini memberi tahu linker untuk memilih satu definisi untuk digunakan oleh semua referensi eksternal dan untuk membuang sisanya. Solusi ini terkadang berguna saat menggabungkan pustaka impor. Jika tidak, kami tidak merekomendasikannya sebagai cara untuk menghindari kesalahan linker.

  • Kesalahan ini dapat terjadi ketika file header menentukan fungsi yang bukan inline. Jika Anda menyertakan file header ini dalam lebih dari satu file sumber, Anda mendapatkan beberapa definisi fungsi dalam yang dapat dieksekusi.

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

    Solusi yang mungkin meliputi:

    • inline Tambahkan kata kunci ke fungsi :

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • Hapus isi fungsi dari file header dan biarkan hanya deklarasi, lalu terapkan fungsi dalam satu dan hanya satu file sumber:

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • Kesalahan ini juga dapat terjadi jika Anda menentukan fungsi anggota di luar deklarasi kelas dalam file header:

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

    Untuk memperbaiki masalah ini, pindahkan definisi fungsi anggota di dalam kelas. Fungsi anggota yang ditentukan di dalam deklarasi kelas secara implisit di-inlin.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • Kesalahan ini dapat terjadi jika Anda menautkan lebih dari satu versi pustaka standar atau CRT. Misalnya, jika Anda mencoba menautkan pustaka CRT ritel dan debug, atau versi statis dan dinamis pustaka, atau dua versi pustaka standar yang berbeda ke yang dapat dieksekusi, kesalahan ini mungkin dilaporkan berkali-kali. Untuk memperbaiki masalah ini, hapus semua kecuali satu salinan setiap pustaka dari perintah tautan. Kami tidak menyarankan Anda mencampur pustaka ritel dan debug, atau versi pustaka yang berbeda, dalam executable yang sama.

    Untuk memberi tahu linker untuk menggunakan pustaka selain default, pada baris perintah, tentukan pustaka yang akan digunakan, dan gunakan opsi /NODEFAULTLIB untuk menonaktifkan pustaka default. Di IDE, tambahkan referensi ke proyek Anda untuk menentukan pustaka yang akan digunakan, lalu buka dialog Halaman Properti untuk proyek Anda, dan di halaman Linker, properti Input , atur abaikan Semua Pustaka Default, atau Abaikan properti Pustaka Default Tertentu untuk menonaktifkan pustaka default.

  • Kesalahan ini dapat terjadi jika Anda mencampur penggunaan pustaka statis dan dinamis saat Anda menggunakan opsi /clr . Misalnya, kesalahan ini dapat terjadi jika Anda membuat DLL untuk digunakan dalam executable yang ditautkan di CRT statis. Untuk memperbaiki masalah ini, gunakan hanya pustaka statis atau hanya pustaka dinamis untuk seluruh pustaka yang dapat dieksekusi dan untuk pustaka apa pun yang Anda buat untuk digunakan dalam yang dapat dieksekusi.

  • Kesalahan ini dapat terjadi jika simbol adalah fungsi kemasan (dibuat dengan mengkompilasi dengan /Gy) dan disertakan dalam lebih dari satu file, tetapi diubah di antara kompilasi. Untuk memperbaiki masalah ini, kompilasi ulang semua file yang menyertakan fungsi paket.

  • Kesalahan ini dapat terjadi jika simbol didefinisikan secara berbeda dalam dua objek anggota di pustaka yang berbeda, dan kedua objek anggota digunakan. Salah satu cara untuk memperbaiki masalah ini ketika pustaka ditautkan secara statis adalah dengan menggunakan objek anggota hanya dari satu pustaka, dan menyertakan pustaka tersebut terlebih dahulu pada baris perintah linker. Untuk menggunakan kedua simbol, Anda harus membuat cara untuk membedakannya. Misalnya, jika Anda dapat membuat pustaka dari sumber, Anda dapat membungkus setiap pustaka dalam namespace layanan yang unik. Atau, Anda dapat membuat pustaka pembungkus baru yang menggunakan nama unik untuk membungkus referensi ke salah satu pustaka asli, menautkan pustaka baru ke pustaka asli, lalu menautkan yang dapat dieksekusi ke pustaka baru Anda alih-alih pustaka asli.

  • Kesalahan ini dapat terjadi jika extern const variabel didefinisikan dua kali, dan memiliki nilai yang berbeda dalam setiap definisi. Untuk memperbaiki masalah ini, tentukan konstanta hanya sekali, atau gunakan namespace layanan atau enum class definisi untuk membedakan konstanta.

  • Kesalahan ini dapat terjadi jika Anda menggunakan uuid.lib dalam kombinasi dengan file .lib lainnya yang menentukan GUID (misalnya, oledb.lib dan adsiid.lib). Contohnya:

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

    Untuk memperbaiki masalah ini, tambahkan /FORCE:MULTIPLE ke opsi baris perintah linker, dan pastikan bahwa uuid.lib adalah pustaka pertama yang dirujuk.