Nesne dosyalarında çözülmemiş harici sembol


180

Visual Studio'da kodlama sırasında çözülemeyen bir dış sembol hatası aldım ve ne yapacağım hakkında hiçbir fikrim yok. Neyin yanlış olduğunu bilmiyorum. Lütfen beni deşifre eder misiniz? Ne tür hataları nerede aramalıyım?

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

26
Çözülmemiş sembol, bir yerde bildirdiğiniz ancak hiçbir zaman tanımlamadığınız semboldür. Genellikle, bazı üçüncü taraf kitaplığının başlık dosyasını eklediğiniz ancak bağlayıcıya kitaplık için ilgili .obj dosyalarını nerede bulacağını söylemediğiniz anlamına gelir.
deong

7
Oldukça yaygın bir hata, bir işlevi bağımsız olarak tanımlamanız ve .cpp dosyanızdaki sınıf seçiciyi unutmanızdır : Bunu yapın (yanlış): void myFunc() { /* do stuff */ } Bunun yerine (sağda): void A::myFunc() { /* do stuff */ }
jave.web 11:15

.Cpp dosyanızda daha fazla tanımlamak istemiyorsanız, doğrudan başlık dosyanıza köşeli ayraçlar da ekleyebilirsiniz void myFunc() {};.
Patapoom

Yanıtlar:


303

Bu hata genellikle bazı işlevlerin bir bildirimi olduğu, ancak bir tanımı olmadığı anlamına gelir.

Misal:

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

// A.cpp

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

Sizin durumunuzda, tanım bulunamıyor. Sorun, bazı işlev bildirimleri getiren bir başlık dosyası eklemeniz olabilir, ancak aşağıdakilerden birini yapabilirsiniz:

  1. cpp dosyanızdaki işlevleri tanımlamayın (bu kodu kendiniz yazdıysanız)
  2. tanımları içeren lib / dll dosyasını dahil etmeyin

Yaygın bir hata, bir işlevi bağımsız olarak tanımlamanız ve sınıf seçiciyi (örneğin A::, .cpp dosyanızda) unutmanızdır :

Yanlış: void myFunc() { /* do stuff */ }
Doğru: void A::myFunc() { /* do stuff */ }


2
Söz konusu lib dosyasını projeme nasıl ekleyebilirim?
tmj

@tMJ Hangi ortamı kullandığınıza bağlıdır. Çevrimiçi olarak veya bu sitede öğreticiler ararım.
Chris Morris

@ChrisMorris İşlevin tanımı, uygun bir şekilde bağlanmadığım için kullanılamıyordu. Ancak, dll bellekte olmadığından ve bir LoadLibrary çağrısı yoluyla yüklenmesi gerektiğinden. (FTR)
tmj

2
Son tavsiye tam olarak burada sorun oldu. Bunun void myFunc() {}yerine yapıyordum A::void myFunc() {}.
Charles

Mükemmel cevap. Aslında yöntemi başka bir yerden kopyaladıktan sonra hem (1) hem de A :: bölümünü unutmuştum.
17'de RoG

24

Çözümünüzde referansta bulunduğunuz tüm kaynak dosyaları eklediğinizi kontrol edin.

FieldProjenizdeki sınıfın kaynak dosyasını (ve dolayısıyla uygulamasını) dahil etmiyorsanız, derlenmez ve derleme sırasında bağlantı kuramazsınız.

Alternatif olarak, belki de statik veya dinamik bir kitaplık kullanıyorsunuz ve bağlayıcıya .libs hakkında bilgi vermeyi mi unuttunuz ?


3
Doğru lib dosyalarına başvurmak sorunu çözdü. Lib dizinine ve lib dosyalarına başvurmak için Project-> Properties-> Linker-> General-> Ek Kütüphane Dizinlerini ve Project-> Properties-> Linker-> Input-> Ek Bağımlılıkları Kullanın
zak

11

Bir kitaplık eksik veya dahil gibi görünüyor, getName, getType vb ... sahip kitaplığınızın hangi sınıf anlamaya çalışın ve bunu başlık dosyasına veya kullanarak koyun #include.

Ayrıca bunlar harici bir kütüphaneden geliyorsa, proje dosyanızda bunlara başvurduğunuzdan emin olun. Örneğin, bu sınıf bir abc.lib dosyasına aitse, Visual Studio'nuzda

  1. Proje Özellikleri'ne tıklayın.
  2. Yapılandırma Özellikleri, C / C ++, Oluştur, Ek İçerme Dizinleri altında abc.lib konumuna işaret ettiğinizi doğrulayın. Bağlayıcı, Giriş altında, Ek Bağımlılıklar altında abc.lib dosyasına sahip olduğunuzdan emin olun.

9

Ben sadece .cpp dosyasında, doğru .h dosyasında bildirilen ve .c dosyasında tanımlanan bir işlev çağıramazsınız sorunu gördüm. Bir bağlayıcı hatasıyla karşılaşıldı. Bu arada her zamanki .c dosyasından işlevi çağırabilirim. Muhtemelen çağrı kurallarına bağlıdır. Çözüm, her .h dosyasına aşağıdaki preproc satırlarını eklemekti:

#ifdef __cplusplus
extern "C"
{
#endif

ve bunlar sonunda

#ifdef __cplusplus
}
#endif

7

Projemin x64 projesi olarak derlendiği bir hatayla karşılaştım . x86 olarak derlenmiş bir kütüphane kullandım .

Kütüphaneyi x64 olarak derledim ve çözdüm.


5

bazen yeni bir başlık dosyası eklenirse ve bu hata bu nedenle gelmeye başlarsa, kurtulmak için de kitaplık eklemeniz gerekir unresolved external symbol.

Örneğin:

#include WtsApi32.h

ihtiyacınız olacak:

#pragma comment(lib, "Wtsapi32.lib") 

4

Aynı bağlantı hataları vardı, ama başka bir dll başvurulan bir test projesinden. _declspec(dllexport)Hata iletisinde belirtilen her işlevin önüne eklendikten sonra bağlantının iyi çalıştığını öğrendim .


3

Sebepler ve çarelere ilişkin hususların çoğunun bu konudaki tüm katılımcılar tarafından ele alındığını düşünüyorum. Ben sadece 'çözülmemiş harici' sorunum için işaret etmek istiyorum, bu beklenenden farklı ikame makro olarak tanımlanan bir veri türü neden oldu, bu yanlış tip söz konusu işleve ve tür işleviyle sağlanan sonuçlanır hiçbir zaman tanımlanmadı, çözülemedi. Özellikle, C / C ++ -> Dil altında, 'Hayır (/ Zc: wchar_t-)' olarak tanımlanmış ancak benim durumumda olmayan 'WChar_t Yerleşik Olarak Uygula' adlı bir özellik vardır.


teşekkürler, bu benim kurulum neden sorun ('Hayır (/ Zc: wchar_t-)')
Noypi Gilas

2

Yukarıdaki Chris Morris'in mükemmel cevabına ek olarak, saf olarak ayarlanmamış ancak kendi uygulamasına sahip olmayan bir sanal yönteme başvuruyorsanız, aynı hatayı almanın çok ilginç bir yolunu buldum. Tam olarak aynı nedendir (derleyici yöntemin bir uygulamasını ve bu nedenle dolandırıcıları bulamaz), ancak IDE'm bu hatayı en azından biraz yakalamadı.

örneğin, aşağıdaki kod aynı hata iletisiyle bir derleme hatası alır:

//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;
    }
}

Ancak, IamInterface myFunc () saf bir sanal yöntem ("uygulanması gereken bir yöntem," yöntem "geçersiz kılınabilir bir yöntem olan bir sanal yöntem daha) derleme hatası ortadan kaldırır.

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

Bu bir sonraki StackOverFlow kişi kodu adım yardımcı olur umut!



2

Başlık dosyalarınızı şununla süslediğinizden emin olun:

#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H

// your header code here

#endif

Bunu da içeren kötü şeyler,


8
Kullanmaya ne dersiniz #pragma once?
Allen Linatoc

2

Yine başka bir olası sorun (bir süredir başımı kaşıyorum):

İşlevlerinizi inline, - tabii ki! - olarak tanımlarsanız , bir cpp olarak değil , başlıkta (veya satır içi dosyada) tanımlanmaları gerekir . Benim durumumda, satır içi dosyadaydılar , ancak yalnızca platforma özgü bir uygulama oldukları için ve bir cpp , başlık yerine bu karşılık gelen inl dosyasını içeriyordu . Evet, olmaz.

Bunu da burada bırakacağımı sanıyordum, belki başka biri de aynı sorunla karşılaşır ve burada bulur.


1
Bunu kime düşürdüyse: En azından cevabın neden yanlış ya da yardımcı olmadığını düşündüğünüz bir yorum bırakın . Yorum içermeyen bir aşağı oy en iyi ihtimalle değersizdir.
Johann Studanski

1

Bununla sadece zor zamanlar geçirdim. Her şey mantıklı bir şekilde kuruldu. Bir kurucu ilan ettim ama tanımlayamadım

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

Bu kadar basit bir şeyi unuttuğumda neredeyse klavyemi kafama çarptım.


1

Uzun zamandır ilk kez bazı C ++ yapıyorum ve bu C ++ için biraz benzersiz olduğundan, işlev tanımı için ClassName :: öneki eklemeyi unuttuğumda bu hatayı alıyorum. Bunu da kontrol etmeyi unutmayın!


1

Bu bağlayıcı hatasının olası bir nedeni inline, bildirilen ancak daha sonra başka bir yere dahil edilen bir başlık dosyasında tanımlanmayan işlevler olabilir . Satır içi işlevler, kullanıldıkları her çeviri biriminde tanımlanmalıdır.


0

işaretçiler

Bu sorunu yaşadım ve işaretçi kullanarak çözdüm. Bunun sizin sorununuz olmadığını görüyorum ama bundan söz edeceğimi düşündüm, çünkü bunu bir saat önce gördüğümde burada olmasını isterdim. Benim sorunum statik bir üye değişkeni tanımlamadan tanımlamakla ilgiliydi (diğer kurulumlardan sonra gelmesi gereken tanım) ve elbette bir işaretçinin bir tanıma ihtiyacı yoktur. Aynı derecede temel hata: P


3
Burada bir örnek oldukça faydalı olacaktır.
moffeltje

0

Benim sorunum bir tanesinde cpptanımlanmış dosya yoktu oldu. Visual Studio cppprojede dosya var, ancak tamamen başka bir şey inşa ediyor çünkü bu çok kafa karıştırıcı olabilir .


0

Benim sorunum şuydu: Ctor'u "çözülemeyen dış" olan sınıfın ileri bildirimini yapmak zorunda kaldım .

Hatayı aldığım dosyada, böyle bir şey koymak zorunda kaldım:

#include "ClassB" 

class ClassB; // this solved the problem

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

Tabii ki, projem çok daha karmaşık ve bu sadece bir snippet örneğidir. Ayrıca ad alanlarını kullanırken, bunları da bildirin .


0

Sorunun ana dosyamın .cyerine uzantıya sahip olduğunu bulmak için birkaç saat geçirdim.cpp

:/


0

Kontrol etmek için başka bir olasılık, bu sefer benim sorunumdu.

Fonksiyonu kütüphaneye ekledim ve kütüphanenin çıktı klasörünü arama yoluna dahil ettim.

Ancak daha önce listelenen kütüphanenin daha eski bir sürümüne sahip bir klasörüm vardı, bu yüzden VS eski kütüphaneyi kullanıyordu ve elbette yeni işlevi bulamıyordu.


0

Yerleştirme işlevleri olarak ekleme veya çıkarma operatörlerini aşırı yüklemeye çalışmadığınızdan emin olun. Ben bu sorunu vardı ve sadece ben o anahtar kelime kaldırıldığında gitti.


0

Benim durumumda buna ne sebep olmuştu:

Foo.cppFoo.h olmadan büyük bir dosyam vardı. Foo.cppşöyle başladı:

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

"Statik" anahtar kelimesini kaldırdım ve Foo.hbununla bir ekledim :

extern int var;

Hatayı görüyor musunuz?

Ad alanı bildirimi diğer kodlara gömüldüğünden, var'ın aslında bir ad alanında tanımlandığını tamamen kaçırdım. Çözüm, extern'i şu şekilde değiştirmektir:

namespace NS {
     extern int var;
}

0

"Çözümlenmemiş harici sembol" hatasının olası bir nedeni, işlev çağırma kuralı olabilir.

Tüm kaynak dosyaların aynı standardı (.c veya .cpp) kullandığından emin olun veya arama kuralını belirtin.

Aksi takdirde, bir dosya bir C dosyası (kaynak.c) ve başka bir dosya bir .cpp dosyasıysa ve aynı başlığa bağlanırsa, işlev ilk olarak tanımlandığı için "çözülmemiş dış simge" hatası atılır C cdecl işlevi, ancak daha sonra aynı üstbilgiyi kullanan C ++ dosyası bir C ++ işlevi arayacaktır.

"Çözümlenmemiş harici sembol hatasını" önlemek için, işlev çağırma kuralının onu kullanan dosyalar arasında aynı tutulduğundan emin olun.


0

Buraya linker hatasından önceki satırlara daha yakından bakmadan önce olası bir açıklama aramaya geldim. Küresel bildirgenin eksik olduğu ek bir yürütülebilir dosya olduğu ortaya çıktı!


0

Ben de aynı hatayı yaşadım ve ben değiştirerek bunu önlemek için yönetmek ;ile {}başlık dosyasında.

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

Olduğu zaman void xyzMethod();derlemek istemiyordu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.