Simbol eksternal yang tidak terselesaikan dalam file objek

180

Selama pengkodean di Visual Studio saya mendapat kesalahan simbol eksternal yang tidak terselesaikan dan saya tidak tahu harus berbuat apa. Saya tidak tahu apa yang salah. Bisakah Anda menguraikan saya? Di mana saya harus mencari kesalahan apa?

1>Form.obj : error LNK2019: unresolved external symbol "public: class Field * __thiscall Field::addField(class Field *)" (?addField@Field@@QAEPAV1@PAV1@@Z) referenced in function "public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Form@@QAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Field::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Field@@UAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0InputField@@QAE@AAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::prompt(void)" (?prompt@Field@@UAEXXZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getName(void)" (?getName@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getType(void)" (?getType@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::describe(void)" (?describe@Field@@UAEXXZ)
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals
Novellizator
sumber
26
Simbol yang belum terselesaikan adalah simbol yang telah Anda deklarasikan di suatu tempat tetapi tidak pernah ditentukan. Biasanya, itu berarti Anda telah # memasukkan file header perpustakaan pihak ketiga tetapi tidak memberi tahu linker tempat menemukan file .obj yang sesuai untuk perpustakaan.
deong
7
Kesalahan yang cukup umum adalah bahwa Anda mendefinisikan suatu fungsi sebagai standalone dan melupakan pemilih kelas dalam file .cpp Anda : Anda melakukan ini (salah): void myFunc() { /* do stuff */ } Alih-alih ini (kanan): void A::myFunc() { /* do stuff */ }
jave.web
Anda juga dapat menambahkan kurung langsung di Anda sundulan berkas jika Anda tidak ingin mendefinisikan lebih dalam file cpp Anda, seperti itu: void myFunc() {};.
Patapoom

Jawaban:

303

Kesalahan ini sering berarti bahwa beberapa fungsi memiliki deklarasi, tetapi bukan definisi.

Contoh:

// A.hpp
class A
{
public:
  void myFunc(); // Function declaration
};

// A.cpp

// Function definition
void A::myFunc()
{
  // do stuff
}

Dalam kasus Anda, definisi tidak dapat ditemukan. Masalahnya mungkin Anda menyertakan file header, yang membawa beberapa deklarasi fungsi, tetapi Anda juga:

  1. jangan mendefinisikan fungsi dalam file cpp Anda (jika Anda menulis kode ini sendiri)
  2. jangan sertakan file lib / dll yang berisi definisi

Kesalahan umum adalah Anda mendefinisikan fungsi sebagai mandiri dan melupakan pemilih kelas, misalnya A::, dalam file .cpp Anda :

Salah: void myFunc() { /* do stuff */ }
kanan: void A::myFunc() { /* do stuff */ }

Chris Morris
sumber
2
Bagaimana cara memasukkan file lib tersebut dalam proyek saya?
tmj
@ tMJ Tergantung pada lingkungan apa yang Anda gunakan. Saya akan mencari tutorial online, atau di situs ini.
Chris Morris
@ChrisMorris Definisi fungsi tidak tersedia bukan karena saya tidak menautkannya dengan benar atau sesuatu. Tetapi, karena dll tidak ada dalam memori dan harus dimuat melalui panggilan LoadLibrary. (FTR)
tmj
2
Nasihat terakhir persis masalah di sini. Saya melakukan void myFunc() {}bukan A::void myFunc() {}.
Charles
Jawaban yang brilian. Saya benar-benar lupa kedua (1) dan kemudian bagian A :: setelah menyalin metode dari tempat lain.
RoG
24

Periksa apakah Anda menyertakan semua file sumber dalam solusi yang Anda rujuk.

Jika Anda tidak menyertakan file sumber (dan dengan demikian implementasinya) untuk kelas Fielddalam proyek Anda, itu tidak akan dibangun dan Anda tidak akan dapat menautkan selama kompilasi.

Atau, mungkin Anda menggunakan perpustakaan statis atau dinamis dan lupa memberi tahu tautan tentang tautan .lib?

Konrad
sumber
3
Merujuk file lib yang benar menyelesaikan masalah. Gunakan Project-> Properties-> Linker-> General-> Direktori Perpustakaan Tambahan dan Project-> Properties-> Linker-> Input-> Dependensi Tambahan untuk merujuk direktori lib dan file lib
zak
11

Tampaknya ada perpustakaan yang hilang atau termasuk, Anda dapat mencoba mencari tahu kelas perpustakaan Anda yang memiliki getName, getType dll ... dan memasukkannya ke dalam file header atau menggunakan #include.

Juga jika ini berasal dari perpustakaan eksternal, pastikan Anda merujuknya pada file proyek Anda. Misalnya, jika kelas ini milik abc.lib maka di Visual Studio Anda

  1. Klik pada Properti Proyek.
  2. Pergi ke Properti Konfigurasi, C / C ++, Hasilkan, verifikasi Anda arahkan ke lokasi abc.lib di bawah Direktori Sertakan Tambahan. Di bawah Linker, Input, pastikan Anda memiliki abc.lib di bawah Ketergantungan Tambahan.
Fylix
sumber
9

Saya baru saja melihat masalah saya tidak bisa memanggil fungsi dari utama dalam file .cpp, dinyatakan dengan benar dalam file .h dan didefinisikan dalam file .c. Mengalami kesalahan tautan. Sementara itu saya dapat memanggil fungsi dari file .c biasa. Mungkin itu tergantung pada konvensi panggilan. Solusi adalah menambahkan baris preproc berikut di setiap file .h:

#ifdef __cplusplus
extern "C"
{
#endif

dan ini pada akhirnya

#ifdef __cplusplus
}
#endif
Alexey257
sumber
7

Saya memiliki kesalahan ketika proyek saya dikompilasi sebagai proyek x64 . dan saya telah menggunakan Perpustakaan yang dikompilasi sebagai x86 .

Saya telah mengkompilasi ulang pustaka sebagai x64 dan menyelesaikannya.

Gal Bracha
sumber
5

kadang-kadang jika file header baru ditambahkan, dan kesalahan ini mulai terjadi karena itu, Anda perlu menambahkan perpustakaan juga untuk menyingkirkan unresolved external symbol.

sebagai contoh:

#include WtsApi32.h

akan membutuhkan:

#pragma comment(lib, "Wtsapi32.lib") 
Shashank
sumber
4

Saya memiliki kesalahan tautan yang sama, tetapi dari proyek uji yang mereferensikan dll lain. Mengetahui bahwa setelah menambahkan _declspec(dllexport)di depan setiap fungsi yang ditentukan dalam pesan kesalahan, tautannya berfungsi dengan baik.

meJustAndrew
sumber
3

Saya percaya sebagian besar poin tentang penyebab dan solusi telah dibahas oleh semua kontributor di utas ini. Saya hanya ingin menunjukkan untuk masalah 'eksternal yang belum terselesaikan', itu disebabkan oleh tipe data yang didefinisikan sebagai makro yang diganti secara berbeda dari yang diharapkan, yang menghasilkan tipe yang salah yang dipasok ke fungsi yang dimaksud, dan karena fungsi dengan tipe tidak pernah ditentukan, itu tidak bisa diselesaikan. Secara khusus, di bawah C / C ++ -> Bahasa, ada atribut yang disebut 'Treat WChar_t As Built in Type, yang seharusnya didefinisikan sebagai' No (/ Zc: wchar_t-) 'tetapi tidak dalam kasus saya.

Patrick Nguyen
sumber
terima kasih, ini menyebabkan masalah dari pengaturan saya ('Tidak (/ Zc: wchar_t-)')
Noypi Gilas
2

Selain jawaban yang sangat baik oleh Chris Morris di atas, saya menemukan cara yang sangat menarik Anda dapat menerima kesalahan yang sama ini jika Anda memanggil metode virtual yang belum diatur ke murni tetapi tidak implementasinya sendiri. Ini adalah alasan yang persis sama (kompiler tidak dapat menemukan implementasi metode dan karenanya penjahat), tetapi IDE saya tidak menangkap kesalahan ini sedikit pun.

misalnya, kode berikut akan mendapatkan kesalahan kompilasi dengan pesan kesalahan yang sama:

//code testing an interface
class test
{
   void myFunc(); 
}

//define an interface
class IamInterface
{
    virtual void myFunc();
}

//implementation of the interface
class IamConcreteImpl
{
    void myFunc()
    {
       1+1=2;
    }
}

Namun, mengubah IamInterface myFunc () menjadi metode virtual murni (metode yang "harus" diterapkan, bahwa daripada metode virtual yang merupakan metode yang "dapat" diganti) akan menghilangkan kesalahan kompilasi.

//define an interface
class IamInterface
{
    virtual void myFunc() = 0;
}

Berharap ini membantu orang StackOverFlow berikutnya melangkah melalui kode!

GMLewisII
sumber
2

Lihat Kesalahan Alat Tautan LNK2019 di MSDN, ia memiliki daftar terperinci masalah umum yang menyebabkan LNK2019.

Alessandro Jacopson
sumber
2

Pastikan Anda menghias file header Anda dengan

#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H

// your header code here

#endif

Hal-hal buruk - termasuk ini - dapat terjadi jika Anda tidak melakukannya

Panouden
sumber
8
Bagaimana kalau menggunakan #pragma once?
Allen Linatoc
2

Namun masalah lain yang mungkin terjadi (bahwa saya baru saja menggaruk-garuk kepala selama beberapa waktu):

Jika Anda mendefinisikan fungsi Anda sebagai inline, mereka — tentu saja! —Telah didefinisikan di header (atau file inline ), bukan cpp .
Dalam kasus saya, mereka berada dalam file inline, tetapi hanya karena mereka adalah implementasi platform spesifik, dan cpp termasuk file inl yang sesuai ini ... bukan header. Ya, itu tidak terjadi.

Saya pikir saya akan meninggalkan ini di sini juga, mungkin orang lain mengalami masalah yang sama dan menemukannya di sini.

Johann Studanski
sumber
1
Untuk siapa pun yang memilih ini: Berikan setidaknya komentar mengapa menurut Anda jawabannya salah atau tidak membantu. Downvote tanpa komentar tidak ada gunanya sama sekali.
Johann Studanski
1

Saya hanya mengalami kesulitan dengan ini. Semuanya diatur secara logis. Saya menyatakan konstruktor tetapi tidak mendefinisikannya

class SomeClass
{
   SomeClass();  // needs the SomeClass::SomeClass(){} function defined somewhere, even here
}

Aku hampir membenturkan kepalaku ke keyboard ketika aku lupa sesuatu yang begitu mendasar.

Joe Plante
sumber
1

Saya melakukan beberapa C ++ untuk pertama kalinya dalam waktu yang lama, dan saya mendapatkan kesalahan ini ketika saya lupa menambahkan awalan ClassName :: untuk definisi fungsi, karena ini sedikit unik untuk C ++. Jadi ingatlah untuk memeriksanya juga!

Matthew Hayes
sumber
1

Salah satu kemungkinan penyebab kesalahan penghubung ini juga bisa berupa inlinefungsi yang dideklarasikan tetapi tidak didefinisikan dalam file header yang kemudian disertakan di tempat lain. Fungsi sebaris harus didefinisikan di setiap unit terjemahan tempat mereka digunakan.

bweber
sumber
0

POINTER

Saya punya masalah ini dan menyelesaikannya dengan menggunakan pointer. Saya melihat bahwa ini bukan masalah Anda, tetapi saya pikir saya akan menyebutkannya karena saya berharap hal itu ada di sini ketika saya melihatnya satu jam yang lalu. Masalah saya adalah tentang mendeklarasikan variabel anggota statis tanpa mendefinisikannya (definisi perlu muncul setelah beberapa pengaturan lainnya) dan tentu saja pointer tidak memerlukan definisi. Kesalahan yang sama mendasarnya: P

Rabel
sumber
3
Contoh akan sangat berguna di sini.
moffeltje
0

Masalah saya adalah naskah tidak memiliki cppfile yang ditentukan di dalamnya. Ini bisa sangat membingungkan karena Visual Studio memiliki cppfile dalam proyek tetapi sesuatu yang lain sama sekali sedang dibangun.

ubershmekel
sumber
0

Masalah saya adalah: Saya harus melakukan deklarasi maju kelas yang ctornya adalah "eksternal yang belum terselesaikan".

Dalam file tempat saya mendapatkan kesalahan, saya harus meletakkan sesuatu seperti ini:

#include "ClassB" 

class ClassB; // this solved the problem

class ClassA{
    void foo(){
        ClassB* tmp = new ClassB();
        // ...
    }
};

Tentu saja, proyek saya jauh lebih rumit dan ini hanyalah contoh cuplikan. Juga saat menggunakan ruang nama, deklarasikan juga .

vicrucann
sumber
0

Hanya menghabiskan beberapa jam untuk menemukan bahwa masalahnya adalah file utama saya memiliki ekstensi, .cbukan.cpp

:/

Madhur
sumber
0

Namun kemungkinan lain untuk memeriksa, itu adalah masalah saya saat ini.

Saya telah menambahkan fungsi ke perpustakaan, dan termasuk folder keluaran perpustakaan di jalur pencarian.

Tapi saya juga punya folder dengan versi lama dari perpustakaan yang terdaftar sebelumnya, jadi VS menggunakan perpustakaan lama, dan tentu saja tidak menemukan fungsi baru.

Francesco Dondi
sumber
0

Pastikan Anda tidak mencoba membebani operator penyisipan atau ekstraksi sebagai fungsi inline. Saya memiliki masalah ini dan hanya hilang ketika saya menghapus kata kunci itu.

Beck
sumber
0

Apa yang menyebabkannya dalam kasus saya:

Saya punya file besar Foo.cpptanpa Foo.h. Foo.cppmulai seperti ini:

// ... 100 LOC here ...
namespace NS {
// ... 100 more LOC here ...
static int var;

Saya menghapus kata kunci "statis" dan menambahkan Foo.hdengan ini:

extern int var;

Apakah Anda melihat kesalahannya?

Saya benar-benar merindukan var yang awalnya didefinisikan dalam namespace, karena deklarasi namespace dikubur dalam kode lain. Cara mengatasinya adalah mengubah extern seperti ini:

namespace NS {
     extern int var;
}
Stefan Monov
sumber
0

Alasan yang mungkin untuk kesalahan "Simbol eksternal yang tidak terselesaikan" dapat berupa konvensi pemanggilan fungsi.

Pastikan bahwa semua file sumber menggunakan standar yang sama (.c atau .cpp), atau tentukan konvensi pemanggilan.

Kalau tidak, jika satu file adalah file C (source.c) dan file lain adalah file .cpp, dan mereka menautkan ke header yang sama, maka kesalahan "simbol eksternal yang tidak terselesaikan" akan dibuang, karena fungsi pertama kali didefinisikan sebagai fungsi C cdecl, tetapi kemudian file C ++ menggunakan header yang sama akan mencari fungsi C ++.

Untuk menghindari "Kesalahan simbol eksternal yang tidak terselesaikan", pastikan bahwa konvensi pemanggilan fungsi tetap sama di antara file yang menggunakannya.

Flavio
sumber
0

Saya datang ke sini mencari penjelasan yang mungkin sebelum melihat lebih dekat pada baris sebelum kesalahan linker. Ternyata telah menjadi executable tambahan yang tidak memiliki deklarasi global!

Jerry Miller
sumber
0

Saya baru saja mengalami kesalahan yang sama dan saya berhasil menghindarinya dengan mengganti ;dengan {}di file header.

#ifndef XYZ_h
#define XYZ_h
class XYZ
{
    public:
    void xyzMethod(){}
}
#endif

Ketika itu void xyzMethod();tidak mau dikompilasi.

Lisedra
sumber