Aracılığıyla paylaş


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

'function' işlevinde başvuruda bulunan çözülmemiş dış simge 'symbol'

İşlev için derlenmiş kod bir başvuru veya sembol çağrısı yapar, ancak bağlayıcı, kitaplıkların veya nesne dosyalarının hiçbirinde sembol tanımını bulamıyor.

Bu hata iletisinin ardından önemli hata LNK1120. Hata LNK1120 düzeltmek için önce tüm LNK2001 ve LNK2019 hatalarını düzeltmeniz gerekir.

Olası nedenler

Bu hatayı almanın birçok yolu vardır. Bunların tümü, bağlayıcının çözümleyemediği bir işleve veya değişkene başvuru içerir veya bir tanım bulur. Derleyici, bir simgenin ne zaman bildirİlmiyor olduğunu belirleyebilir, ancak simgenin tanımlanmadığı zamanları belirleyemez. Bunun nedeni tanımın farklı bir kaynak dosya veya kitaplıkta olmasıdır. Bir simgeye başvurulur ancak hiç tanımlanmamışsa, bağlayıcı çözülmemiş bir dış simge hatası oluşturur.

LNK2019 neden olan bazı yaygın sorunlar şunlardır:

Simgenin tanımını içeren kaynak dosya derlenmemiş

Visual Studio'da, simgeyi tanımlayan kaynak dosyanın projenizin bir parçası olarak derlendiğinden emin olun. Eşleşen bir .obj dosyası için ara derleme çıktı dizinini denetleyin. Kaynak dosya derlenmemişse, Çözüm Gezgini'da dosyaya sağ tıklayın ve sonra dosyanın özelliklerini denetlemek için Özellikler'i seçin. Yapılandırma Özellikleri>Genel sayfasında C/C++ Derleyicisi Öğe Türü gösterilmelidir. Komut satırında, tanımı içeren kaynak dosyanın derlendiğinden emin olun.

Simgenin tanımını içeren nesne dosyası veya kitaplığı bağlı değil

Visual Studio'da, sembol tanımını içeren nesne dosyasının veya kitaplığının projenizin bir parçası olarak bağlı olduğundan emin olun. Komut satırında, bağlanılacak dosya listesinin nesne dosyasını veya kitaplığını içerdiğinden emin olun.

Simgenin bildirimi, simgenin tanımıyla aynı yazılmıyor

Hem bildirimde hem de tanımda ve sembolün kullanıldığı veya çağrıldığı her yerde doğru yazım ve büyük harf kullanımını doğrulayın.

İşlev kullanılır, ancak parametrelerin türü veya sayısı işlev tanımıyla eşleşmiyor

İşlev bildiriminin tanımıyla eşleşmesi gerekir. İşlev çağrısının bildirimle eşleştiğinden ve bildirimin tanımla eşleştiğinden emin olun. İşlev şablonlarını çağıran kod, tanımla aynı şablon parametrelerini içeren eşleşen işlev şablonu bildirimlerine de sahip olmalıdır. Şablon bildirimi uyuşmazlığı örneği için Örnekler bölümündeki örnek LNK2019e.cpp bakın.

İşlev veya değişken bildirilir ancak tanımlanmaz

LNK2019, bir üst bilgi dosyasında bir bildirim mevcut olduğunda oluşabilir, ancak eşleşen bir tanım uygulanmaz. Üye işlevleri veya static veri üyeleri için uygulama sınıf kapsamı seçiciyi içermelidir. Bir örnek için bkz . Eksik İşlev Gövdesi veya Değişkeni.

Çağırma kuralı, işlev bildirimi ile işlev tanımı arasında farklıdır

Bazı çağrı kuralları (__cdecl, __stdcall, __fastcallve __vectorcall) süslü adın bir parçası olarak kodlanır. Çağırma kuralının aynı olduğundan emin olun.

C dosyasında bir simge tanımlanır, ancak C++ dosyasında kullanılmadan extern "C" bildirilir

C olarak derlenen bir dosya, değiştirici kullanmadığınız extern "C" sürece, C++ dosyasında bildirilen adlar için symbols dekore edilmiş adlardan farklı olan süslü adlar symbols oluşturur. Bildirimin her simge için derleme bağlantısıyla eşleştiğinden emin olun. Benzer şekilde, C++ dosyasında C programı tarafından kullanılacak bir simge tanımlarsanız, tanımında kullanın extern "C" .

Simge olarak static tanımlanır ve daha sonra dosyanın dışında başvurulur

C++'ta C'den farklı olarak genel sabitlerin bağlantısı vardır static . Bu sınırlamayı geçici olarak çözmek için, başlatmaları bir üst bilgi dosyasına ekleyebilir const ve bu üst bilgiyi .cpp dosyalarınıza ekleyebilir veya değişkeni sabit olmayan bir değişken yapabilir ve buna erişmek için sabit bir başvuru kullanabilirsiniz.

Bir static sınıfın üyesi tanımlanmadı

Sınıf static üyesinin benzersiz bir tanımı olmalıdır, aksi takdirde tek tanım kuralını ihlal eder. static Satır içinde tanımlanmayan bir sınıf üyesi, tam adı kullanılarak bir kaynak dosyada tanımlanmalıdır. Hiç tanımlanmamışsa bağlayıcı LNK2019 oluşturur.

Derleme bağımlılığı yalnızca çözümde proje bağımlılığı olarak tanımlanır

Visual Studio'nun önceki sürümlerinde bu bağımlılık düzeyi yeterliydi. Ancak Visual Studio 2010'dan başlayarak Visual Studio projeden projeye başvuru gerektirir. Projenizin projeden projeye başvurusu yoksa bu bağlayıcı hatasını alabilirsiniz. Düzeltmek için projeden projeye başvuru ekleyin.

Giriş noktası tanımlanmadı

Uygulama kodu, konsol uygulamaları için veya wmain WinMain wWinMain Windows uygulamaları için uygun bir giriş noktası main tanımlamalıdır. Daha fazla bilgi için bkz main . işlev ve komut satırı bağımsız değişkenleri veya WinMain işlevi. Özel giriş noktası kullanmak için (Giriş Noktası Simgesi) bağlayıcı seçeneğini belirtin./ENTRY

Windows uygulamasının ayarlarını kullanarak konsol uygulaması oluşturursunuz

Hata iletisi, işlev function_name başvuruda bulunan çözülmemiş dış simgeye WinMain benziyorsa, yerine /SUBSYSTEM:WINDOWSkullanarak /SUBSYSTEM:CONSOLE bağlantı oluşturun. Bu ayar hakkında daha fazla bilgi ve Visual Studio'da bu özelliği ayarlama yönergeleri için bkz /SUBSYSTEM . (Alt Sistemi Belirtme).

Kodunuzla bağlantılı kitaplıklar ve nesne dosyaları, kodunuzla aynı mimari için derlenmelidir. Proje başvurularınızın projenizle aynı mimari için derlendiğinden emin olun. veya Ek Kitaplık Dizinleri özelliğinin /LIBPATH doğru mimari için oluşturulmuş kitaplıkları işaretdiğinden emin olun.

Farklı kaynak dosyalarda işlev inlining için farklı derleyici seçenekleri kullanırsınız

.cpp dosyalarında tanımlanan iç işlevler kullanmak ve farklı kaynak dosyalarda derleyici seçeneklerinin bir arada kullanılması LNK2019 neden olabilir. Daha fazla bilgi için bkz . İşlev Inlining Sorunları.

Kapsamları dışında otomatik değişkenler kullanırsınız

Otomatik (işlev kapsamı) değişkenleri yalnızca bu işlevin kapsamında kullanılabilir. Bu değişkenler diğer kaynak dosyalarda bildirilip extern kullanılamaz. Bir örnek için bkz . Otomatik (İşlev Kapsamı) Değişkenleri.

İç işlevleri çağırır veya bağımsız değişken türlerini hedef mimarinizde desteklenmeyen iç işlevlere geçirirsiniz

Örneğin, iç işlev AVX2 kullanıyorsanız ancak derleyici seçeneğini belirtmezseniz /ARCH:AVX2 , derleyici iç işlevin bir dış işlev olduğunu varsayar. Derleyici, satır içi yönerge oluşturmak yerine iç ile aynı ada sahip bir dış simgeye çağrı oluşturur. Bağlayıcı bu eksik işlevin tanımını bulmaya çalıştığında LNK2019 oluşturur. Yalnızca hedef mimariniz tarafından desteklenen iç bilgileri ve türleri kullandığınızdan emin olun.

Yerel wchar_t kodu kullanmayan kodla karıştırırsınız

Visual Studio 2005'te yapılan C++ dil uyumluluğu çalışması varsayılan olarak yerel bir tür haline getirildi wchar_t . Tüm dosyalar aynı /Zc:wchar_t ayarlar kullanılarak derlenmemişse, tür başvuruları uyumlu türlere çözümlenmeyebilir. Tüm kitaplık ve nesne dosyalarındaki türlerin uyumlu olduğundan emin wchar_t olun. Bir wchar_t tür tanımından güncelleştirin veya derlerken tutarlı /Zc:wchar_t ayarlarını kullanın.

static Visual Studio 2015'in öncesinde Visual Studio sürümü kullanılarak oluşturulmuş bir kitaplık, UCRT ile bağlandığında LNK2019 hatalara neden olabilir. UCRT üst bilgi dosyaları <stdio.h>, <conio.h>ve <wchar.h>artık birçok *printf* ve *scanf* varyasyonu işlev olarak inline tanımlıyor. Inlined işlevleri daha küçük bir ortak işlevler kümesi tarafından uygulanır. Yalnızca ortak işlevleri dışarı aktaran standart UCRT kitaplıklarında, satır içi işlevler için tek tek exports kullanılamaz. Bu sorunu çözmenin birkaç yolu vardır. Önerdiğimiz yöntem, eski kitaplığı geçerli Visual Studio sürümünüzle yeniden derlemektir. Kitaplık kodunun, hatalara neden olan ve *scanf* işlevlerinin *printf* tanımları için standart üst bilgileri kullandığından emin olun. Yeniden derleyemezseniz eski bir kitaplığın bir diğer seçeneği de bağladığınız kitaplıklar listesine eklemektir legacy_stdio_definitions.lib . Bu kitaplık dosyası, UCRT üst bilgilerinde çizili olan ve *scanf* işlevleri için *printf* sağlarsymbols. Daha fazla bilgi için, Olası yükseltme sorunlarına genel bakış bölümündeki Kitaplıklar bölümüne bakın.

Üçüncü taraf kitaplık sorunları ve vcpkg

Derlemenizin bir parçası olarak üçüncü taraf kitaplığını yapılandırmaya çalışırken bu hatayı görürseniz vcpkg kullanmayı göz önünde bulundurun. vcpkg , kitaplığı yüklemek ve derlemek için mevcut Visual Studio araçlarınızı kullanan bir C++ paket yöneticisidir. vcpkg, üçüncü taraf kitaplıkların büyük ve büyüyen bir listesini destekler. Projenizin bir parçası olarak başarılı derlemeler için gereken tüm yapılandırma özelliklerini ve bağımlılıklarını ayarlar.

Tanılama araçları

Bazen bağlayıcının neden belirli bir sembol tanımını bulamadığını söylemek zordur. Sorun genellikle derlemenize tanımı içeren kodu dahil etmemiş olmanızdır. Veya derleme seçenekleri dış symbolsiçin farklı süslü adlar oluşturmuştur. LNK2019 hataları tanılamanıza yardımcı olabilecek çeşitli araçlar ve seçenekler vardır.

  • /VERBOSE Bağlayıcı seçeneği bağlayıcının hangi dosyalara başvurdığını belirlemenize yardımcı olabilir. Bu seçenek, simgenin tanımını içeren dosyanın derlemenize eklenip eklenmediğini doğrulamanıza yardımcı olabilir.

  • /EXPORTS yardımcı programının ve /SYMBOLS seçenekleriDUMPBIN, .dll ve nesne veya kitaplık dosyalarınızda tanımlananları bulmanıza symbols yardımcı olabilir. Dışarı aktarılan süslü adların bağlayıcının arama yaptığı süslü adlarla eşleştiğinden emin olun.

  • Yardımcı program, UNDNAME dekore edilmiş bir ad için eşdeğer sıralanmamış dış simgeyi gösterebilir.

Örnekler

Burada, LNK2019 hatalarına neden olan birkaç kod örneği ve hataların nasıl düzeltileceğini gösteren bilgiler verilmiştir.

Simge bildirilir ancak tanımlanmaz

Bu örnekte dış değişken bildirilir ancak tanımlanmaz:

// LNK2019.cpp
// Compile by using: cl /EHsc /W4 LNK2019.cpp
// LNK2019 expected
extern char B[100];   // B isn't available to the linker
int main() {
   B[0] = ' ';   // LNK2019
}

Bir değişkenin ve işlevin olarak extern bildirildiği ancak tanım sağlanmayan başka bir örnek aşağıda verilmiştir:

// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
   i++;
   g();
}
int main() {}

g Derlemeye dahil edilen dosyalardan birinde tanımlanmadığı sürece i bağlayıcı LNK2019 oluşturur. Derlemenin bir parçası olarak tanımları içeren kaynak kod dosyasını ekleyerek hataları düzeltebilirsiniz. Alternatif olarak, tanımları içeren dosyaları veya .lib dosyaları bağlayıcıya geçirebilirsiniz.obj.

Veri static üyesi bildirilir ancak tanımlanmaz

LNK2019, bir static veri üyesi bildirildiğinde ancak tanımlanmadığında da oluşabilir. Aşağıdaki örnek LNK2019 oluşturur ve nasıl düzeltileceğini gösterir.

// LNK2019b.cpp
// Compile by using: cl /EHsc LNK2019b.cpp
// LNK2019 expected
struct C {
   static int s;
};

// Uncomment the following line to fix the error.
// int C::s;

int main() {
   C c;
   C::s = 1;
}

Bildirim parametreleri tanımla eşleşmiyor

İşlev şablonlarını çağıran kodun eşleşen işlev şablonu bildirimleri olmalıdır. Bildirimler, tanım ile aynı şablon parametrelerini içermelidir. Aşağıdaki örnek, kullanıcı tanımlı bir işleçte LNK2019 oluşturur ve nasıl düzeltileceğini gösterir.

// LNK2019e.cpp
// compile by using: cl /EHsc LNK2019e.cpp
// LNK2019 expected
#include <iostream>
using namespace std;

template<class T> class
Test {
   // The operator<< declaration doesn't match the definition below:
   friend ostream& operator<<(ostream&, Test&);
   // To fix, replace the line above with the following:
   // template<typename T> friend ostream& operator<<(ostream&, Test<T>&);
};

template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
   return os;
}

int main() {
   Test<int> t;
   cout << "Test: " << t << endl;   // LNK2019 unresolved external
}

Tutarsız wchar_t tür tanımları

Bu örnek, kullanan bir dışarı aktarması WCHARolan ve olarak çözümlenen wchar_tbir DLL oluşturur.

// LNK2019g.cpp
// compile with: cl /EHsc /LD LNK2019g.cpp
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}

Sonraki örnek, önceki örnekteki DLL'yi kullanır ve türler unsigned short* WCHAR* aynı olmadığından LNK2019 oluşturur.

// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);

int main() {
   func(0);
}

Bu hatayı düzeltmek için veya WCHARolarak değiştirin wchar_t unsigned short veya kullanarak /Zc:wchar_t-LNK2019g.cpp derleyin.

Ayrıca bkz.

LNK2019, LNK2001 ve LNK1120 hatalarının olası nedenleri ve çözümleri hakkında daha fazla bilgi için Stack Overflow sorusuna bakın: What is an undefined reference/unresolved external symbol error and how do I fix it?.