LNK2019 Kesalahan Alat Linker
simbol al yang tidak terselesaikan extern'simbol' yang direferensikan dalam fungsi 'function'
Kode yang dikompilasi untuk fungsi membuat referensi atau panggilan ke simbol, tetapi linker tidak dapat menemukan definisi simbol di salah satu pustaka atau file objek.
Pesan kesalahan ini diikuti oleh kesalahan fatal LNK1120. Untuk memperbaiki kesalahan LNK1120, Anda harus memperbaiki semua kesalahan LNK2001 dan LNK2019 terlebih dahulu.
Kemungkinan penyebab
Ada banyak cara untuk mendapatkan kesalahan ini. Semuanya melibatkan referensi ke fungsi atau variabel yang tidak dapat diatasi oleh linker, atau menemukan definisi. Pengkompilasi dapat mengidentifikasi kapan simbol tidak dideklarasikan, tetapi tidak dapat mengetahui kapan simbol tidak ditentukan. Ini karena definisi mungkin berada dalam file atau pustaka sumber yang berbeda. Jika simbol dirujuk tetapi tidak pernah ditentukan, linker menghasilkan kesalahan simbol al yang tidak terselesaikan extern.
Berikut adalah beberapa masalah umum yang menyebabkan LNK2019:
File sumber yang berisi definisi simbol tidak dikompilasi
Di Visual Studio, pastikan file sumber yang menentukan simbol dikompilasi sebagai bagian dari proyek Anda. Periksa direktori output build perantara untuk file .obj yang cocok. Jika file sumber tidak dikompilasi, klik kanan file di Penjelajah Solusi, lalu pilih Properti untuk memeriksa properti file. Halaman Umum Properti>Konfigurasi harus menampilkan Tipe Item Pengkompilasi C/C++. Pada baris perintah, pastikan file sumber yang berisi definisi dikompilasi.
File objek atau pustaka yang berisi definisi simbol tidak ditautkan
Di Visual Studio, pastikan file objek atau pustaka yang berisi definisi simbol ditautkan sebagai bagian dari proyek Anda. Pada baris perintah, pastikan daftar file yang akan ditautkan menyertakan file objek atau pustaka.
Deklarasi simbol tidak dieja sama dengan definisi simbol
Pastikan Anda menggunakan ejaan dan kapitalisasi yang benar dalam deklarasi dan definisi, dan di mana pun simbol digunakan atau dipanggil.
Fungsi digunakan tetapi jenis atau jumlah parameter tidak cocok dengan definisi fungsi
Deklarasi fungsi harus cocok dengan definisi. Pastikan panggilan fungsi cocok dengan deklarasi, dan bahwa deklarasi cocok dengan definisi. Kode yang memanggil templat fungsi juga harus memiliki deklarasi templat fungsi yang cocok yang menyertakan parameter templat yang sama dengan definisi. Untuk contoh ketidakcocokan deklarasi templat, lihat contoh LNK2019e.cpp di bagian Contoh.
Fungsi atau variabel dideklarasikan tetapi tidak ditentukan
LNK2019 dapat terjadi ketika deklarasi ada dalam file header, tetapi tidak ada definisi yang cocok yang diterapkan. Untuk fungsi anggota atau static anggota data, implementasi harus menyertakan pemilih cakupan kelas. Misalnya, lihat Isi Fungsi atau Variabel yang Hilang.
Konvensi panggilan berbeda antara deklarasi fungsi dan definisi fungsi
Beberapa konvensi panggilan (__cdecl
, __stdcall
, __fastcall
, dan __vectorcall
) dikodekan sebagai bagian dari nama yang didekorasi. Pastikan konvensi panggilan sama.
Simbol didefinisikan dalam file C, tetapi dinyatakan tanpa menggunakan extern "C"
dalam file C++
File yang dikompilasi sebagai C membuat nama yang didekorasi untuk simbol yang berbeda dari nama yang didekorasi untuk simbol yang sama yang dideklarasikan dalam file C++, kecuali Anda menggunakan pengubah extern "C"
. Pastikan deklarasi cocok dengan tautan kompilasi untuk setiap simbol. Demikian pula, jika Anda menentukan simbol dalam file C++ yang akan digunakan oleh program C, gunakan extern "C"
dalam definisi.
Simbol didefinisikan sebagai static dan kemudian dirujuk di luar file
Di C++, tidak seperti C, semut global constmemiliki static
tautan. Untuk mengatasi batasan ini, Anda dapat menyertakan const
inisialisasi dalam file header dan menyertakan header tersebut dalam file .cpp Anda, atau Anda dapat membuat variabel non-semutconst dan menggunakan constreferensi semut untuk mengaksesnya.
static Anggota kelas tidak ditentukan
Anggota static kelas harus memiliki definisi unik, atau akan melanggar aturan satu definisi. static Anggota kelas yang tidak dapat didefinisikan sebaris harus ditentukan dalam satu file sumber dengan menggunakan nama yang sepenuhnya memenuhi syarat. Jika tidak didefinisikan sama sekali, linker menghasilkan LNK2019.
Dependensi build hanya didefinisikan sebagai dependensi proyek dalam solusi
Di versi Visual Studio yang lebih lama, tingkat dependensi ini sudah cukup. Namun, dimulai dengan Visual Studio 2010, Visual Studio memerlukan referensi proyek-ke-proyek. Jika proyek Anda tidak memiliki referensi proyek-ke-proyek, Anda mungkin menerima kesalahan linker ini. Tambahkan referensi proyek-ke-proyek untuk memperbaikinya.
Titik masuk tidak ditentukan
Kode aplikasi harus menentukan titik masuk yang sesuai: main
atau wmain
untuk aplikasi konsol, dan WinMain
atau wWinMain
untuk aplikasi Windows. Untuk informasi selengkapnya, lihat main
fungsi dan argumen atau WinMain
fungsi baris perintah. Untuk menggunakan titik entri kustom, tentukan /ENTRY
opsi penghubung (Simbol Titik Entri).
Anda membangun aplikasi konsol dengan menggunakan pengaturan untuk aplikasi Windows
Jika pesan kesalahan mirip dengan simbol WinMain al yang belum terselesaikan yang direferensikan externdalam fungsi function_name, tautkan dengan menggunakan /SUBSYSTEM:CONSOLE
alih-alih /SUBSYSTEM:WINDOWS
. Untuk informasi selengkapnya tentang pengaturan ini, dan untuk petunjuk tentang cara mengatur properti ini di Visual Studio, lihat /SUBSYSTEM
(Tentukan Subsistem).
Anda mencoba menautkan pustaka 64-bit ke kode 32-bit, atau pustaka 32-bit ke kode 64-bit
Pustaka dan file objek yang ditautkan ke kode Anda harus dikompilasi untuk arsitektur yang sama dengan kode Anda. Pastikan pustaka referensi proyek Anda dikompilasi untuk arsitektur yang sama dengan proyek Anda. Pastikan /LIBPATH
properti Direktori Pustaka Tambahan menunjuk ke pustaka yang dibuat untuk arsitektur yang benar.
Anda menggunakan opsi pengkompilasi yang berbeda untuk fungsi inlining dalam file sumber yang berbeda
Menggunakan fungsi inlined yang ditentukan dalam file .cpp dan fungsi pencampuran yang menginlining opsi pengkompilasi dalam file sumber yang berbeda dapat menyebabkan LNK2019. Untuk informasi selengkapnya, lihat Masalah Inlining Fungsi.
Anda menggunakan variabel otomatis di luar cakupannya
Variabel otomatis (cakupan fungsi) hanya dapat digunakan dalam cakupan fungsi tersebut. Variabel ini tidak dapat dideklarasikan extern
dan digunakan dalam file sumber lainnya. Misalnya, lihat Variabel Otomatis (Cakupan Fungsi).
Anda memanggil fungsi intrinsik atau meneruskan jenis argumen ke fungsi intrinsik yang tidak didukung pada arsitektur target Anda
Misalnya, jika Anda menggunakan intrinsik AVX2 , tetapi jangan tentukan /ARCH:AVX2
opsi pengkompilasi, pengkompilasi mengasumsikan bahwa intrinsik adalah externfungsi al. Alih-alih menghasilkan instruksi sebaris, pengkompilasi menghasilkan panggilan ke externsimbol al dengan nama yang sama dengan intrinsik. Ketika linker mencoba menemukan definisi fungsi yang hilang ini, itu menghasilkan LNK2019. Pastikan Anda hanya menggunakan intrinsik dan jenis yang didukung oleh arsitektur target Anda.
Anda mencampur kode yang menggunakan asli wchar_t
dengan kode yang tidak
Pekerjaan kesesuaian bahasa C++ yang dilakukan di Visual Studio 2005 membuat wchar_t
jenis asli secara default. Jika tidak semua file telah dikompilasi dengan menggunakan pengaturan yang sama /Zc:wchar_t
, referensi jenis mungkin tidak mengatasi jenis yang kompatibel. Pastikan wchar_t
jenis di semua pustaka dan file objek kompatibel. Perbarui dari wchar_t
typedef, atau gunakan pengaturan /Zc yang konsisten :wchar_t saat Anda mengkompilasi.
Anda mendapatkan kesalahan untuk *printf*
fungsi dan *scanf*
saat menautkan pustaka warisan static
static Pustaka yang dibuat menggunakan versi Visual Studio sebelum Visual Studio 2015 dapat menyebabkan kesalahan LNK2019 saat ditautkan dengan UCRT. File <stdio.h>
header UCRT , <conio.h>
, dan <wchar.h>
sekarang menentukan banyak *printf*
dan *scanf*
variasi sebagai inline
fungsi. Fungsi inlined diimplementasikan oleh serangkaian fungsi umum yang lebih kecil. Ekspor individual untuk fungsi inlined tidak tersedia di pustaka UCRT standar, yang hanya mengekspor fungsi umum. Ada beberapa cara untuk mengatasi masalah ini. Metode yang kami sarankan adalah membangun kembali pustaka warisan dengan versi Visual Studio Anda saat ini. Pastikan kode pustaka menggunakan header standar untuk definisi *printf*
fungsi dan *scanf*
yang menyebabkan kesalahan. Opsi lain untuk pustaka warisan yang tidak dapat Anda bangun ulang adalah menambahkan legacy_stdio_definitions.lib
ke daftar pustaka yang Anda tautkan. File pustaka ini menyediakan simbol untuk *printf*
fungsi dan *scanf*
yang di-inlin di header UCRT. Untuk informasi selengkapnya, lihat bagian Pustaka di Gambaran Umum potensi masalah peningkatan.
Masalah pustaka pihak ketiga dan vcpkg
Jika Anda melihat kesalahan ini saat mencoba mengonfigurasi pustaka pihak ketiga sebagai bagian dari build Anda, pertimbangkan untuk menggunakan vcpkg. vcpkg adalah manajer paket C++ yang menggunakan alat Visual Studio yang ada untuk menginstal dan membangun pustaka. vcpkg mendukung daftar pustaka pihak ketiga yang besar dan berkembang. Ini mengatur semua properti konfigurasi dan dependensi yang diperlukan untuk build yang berhasil sebagai bagian dari proyek Anda.
Alat diagnosis
Terkadang sulit untuk mengetahui mengapa linker tidak dapat menemukan definisi simbol tertentu. Seringkali masalahnya adalah Anda belum menyertakan kode yang berisi definisi dalam build Anda. Atau, opsi build telah membuat nama yang didekorasi yang berbeda untuk externsimbol al. Ada beberapa alat dan opsi yang dapat membantu Anda mendiagnosis kesalahan LNK2019.
Opsi
/VERBOSE
linker dapat membantu Anda menentukan file mana yang dirujuk oleh linker. Opsi ini dapat membantu Anda memverifikasi apakah file yang berisi definisi simbol disertakan dalam build Anda.Opsi
/EXPORTS
DUMPBIN dan/SYMBOLS
utilitas dapat membantu Anda menemukan simbol mana yang ditentukan dalam file .dll dan objek atau pustaka Anda. Pastikan nama yang didekorasi yang diekspor cocok dengan nama yang didekorasi yang dicari linker.UNDNAME Utilitas dapat menunjukkan simbol al yang tidak terdekorasi externyang setara untuk nama yang didekorasi.
Contoh
Berikut adalah beberapa contoh kode yang menyebabkan kesalahan LNK2019, bersama dengan informasi tentang cara memperbaiki kesalahan.
Simbol dideklarasikan tetapi tidak ditentukan
Dalam contoh ini, externvariabel al dideklarasikan tetapi tidak ditentukan:
// 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
}
Berikut adalah contoh lain di mana variabel dan fungsi dinyatakan sebagai extern
tetapi tidak ada definisi yang disediakan:
// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
i++;
g();
}
int main() {}
Kecuali i
dan g
didefinisikan dalam salah satu file yang disertakan dalam build, linker menghasilkan LNK2019. Anda dapat memperbaiki kesalahan dengan menyertakan file kode sumber yang berisi definisi sebagai bagian dari kompilasi. Atau, Anda dapat meneruskan .obj
file atau .lib
file yang berisi definisi ke linker.
static Anggota data dinyatakan tetapi tidak ditentukan
LNK2019 juga dapat terjadi ketika static anggota data dinyatakan tetapi tidak ditentukan. Sampel berikut menghasilkan LNK2019, dan menunjukkan cara memperbaikinya.
// 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;
}
Parameter deklarasi tidak cocok dengan definisi
Kode yang memanggil templat fungsi harus memiliki deklarasi templat fungsi yang cocok. Deklarasi harus menyertakan parameter templat yang sama dengan definisi. Sampel berikut menghasilkan LNK2019 pada operator yang ditentukan pengguna, dan menunjukkan cara memperbaikinya.
// 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
}
Definisi jenis yang tidak konsisten wchar_t
Sampel ini membuat DLL yang memiliki ekspor yang menggunakan WCHAR
, yang diselesaikan ke wchar_t
.
// LNK2019g.cpp
// compile with: cl /EHsc /LD LNK2019g.cpp
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}
Sampel berikutnya menggunakan DLL dalam sampel sebelumnya, dan menghasilkan LNK2019 karena jenis unsigned short*
dan WCHAR*
tidak sama.
// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);
int main() {
func(0);
}
Untuk memperbaiki kesalahan ini, ubah unsigned short
ke wchar_t
atau WCHAR
, atau kompilasi LNK2019g.cpp dengan menggunakan /Zc:wchar_t-
.
Lihat juga
Untuk informasi selengkapnya tentang kemungkinan penyebab dan solusi untuk kesalahan LNK2019, LNK2001, dan LNK1120, lihat pertanyaan Stack Overflow: What is an undefined reference/unresolved external symbol error and how do I fix it?
.
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk