windows程式設計原始碼:無法解析的外部符號 [email
作者:mickole
出處:http://www.cnblogs.com/mickole/
windows程式設計原始碼在vs2015上執行出現:
無法解析的外部符號 [email protected]
1>HelloWin.obj : error LNK2019: 無法解析的外部符號 [email protected],該符號在函式 "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" ([email protected]
1>D:\MyProgramTest\Hellowin\Debug\Hellowin.exe : fatal error LNK1120: 1 個無法解析的外部命令
解決辦法:
(1)首先必須在開頭引入標頭檔案#include <mmSystem.h>
(2)在解決方案中>>>>右擊選擇>>>>屬性>>>>配置屬性> >>>連結器>>>>輸入>>>>附加依賴項中,寫入winmm.lib,方可。
**********************************************************************************************
/*------------------------------------------------------------
HELLOWIN.C -- Displays "Hello, Windows !" in client area
------------------------------------------------------------*/
#include <windows.h>
//#pragma comment(lib,"winmm.lib")
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows !"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
編譯結果:
error LNK2019: 無法解析的外部符號
fatal error LNK1120: 1 個無法解析的外部
解決方案:在#include<windows.h>後面補上#pragma comment(lib,"winmm.lib")
問題分析:出現這種情況就是專案在編譯時找不到你所引用的庫檔案,或者你自己宣告的虛擬函式沒有定義,二者都會導致連結錯誤,找到這個函式或者類所在的庫,連線的時候記得包含進來就可以了。在include行結束後,在用#pragma comment(lib, "xxxxx")把預設沒有的庫都加上。
要知道哪個庫沒有,編譯出錯後看看是哪個API無法LINK,然後查MSDN關於該API的描述,一般在最下面會有說明,比如是哪個版本WINDOWS開始支援該函式,標頭檔案是哪個,include用哪個,庫用哪個等等。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
無法解析的外部符號“symbol”,該符號在函式“function”中被引用
在 function 中找到了未定義的外部符號 (symbol)。若要解決此錯誤,請提供符號定義或移除引用它的程式碼。
在 Visual C++ .NET 2003 中,如果使用了 /clr 而未將 CRT 連結到可執行檔案,將生成此錯誤。任何由編譯器在未使用 /clr:initialAppDomain 時生成的物件程式碼都包含對 _check_commonlanguageruntime_version 函式的引用,該函式在 C 執行時庫 (CRT) 中定義。如果應用程式在執行庫的版本 1 上執行,該函式將會生成一個錯誤資訊。當前編譯器生成的程式碼與執行庫的版本 1 不相容。因此,如果在 Visual C++ .NET 2003 中編譯時不使用 CRT,則應在程式碼中包含 _check_commonlanguageruntime_version 函式的定義。作為使用 _check_commonlanguageruntime_version 函式的替代方法,您可以與 nochkclr.obj 連結。nochkclr.obj 包含該函式的一個空版本,當您在執行庫的版本 1 上執行應用程式時,nochkclr.obj 不生成錯誤資訊。若要使用當前編譯器版本生成應用程式以在執行庫的以前版本上執行,應使用 /clr:InitialAppDomain。
若要生成一個純 MSIL 可執行檔案(不與 CRT 連結),則必須在專案中定義該函式,而不能使用 nochkclr.obj(.obj 是本機程式碼)。有關可驗證程式碼的更多資訊,請參見產生可驗證的 C++ 託管擴充套件元件。有關從託管 C++ 專案建立純 MSIL 輸出檔案的更多資訊,請參見將 C++ 託管擴充套件專案從混合模式轉換成純 IL。
本主題的其餘部分討論 LNK2019 的其他原因。
請看下面的示例:
extern int i;
extern void g();
void f()
{
i++;
g();
}
int main()
{
}
如果在生成中包含的某個檔案中沒有定義 i 和 g,連結器將生成 LNK2019。可以新增這些定義,方法是將包含這些定義的原始碼檔案包括為編譯的一部分。或者可以將包含這些定義的 .obj 或 .lib 檔案傳遞給連結器。
對於從早期版本升級到當前版本的 C++ 專案,如果定義了 __UNICODE 並且入口點為 WinMain,需要將入口點函式的名稱更改為 _tWinMain 或 _tmain。
導致 LNK2019 的常見問題有:
符號宣告包含拼寫錯誤,以致於符號宣告與符號定義不同。
使用了一個函式,但其引數的型別或數量與函式定義不匹配。
函式宣告使用和函式定義使用中的呼叫約定(__cdecl、__stdcall 或 __fastcall)不同。
符號定義在編譯為 C 程式的檔案中,而符號是在 C++ 檔案中不帶 extern "C" 修飾符宣告的。在此情況下,請修改宣告,例如不是使用:
extern int i;
extern void g();
而使用:
extern "C" int i;
extern "C" void g();
同樣,如果在將由 C 程式使用的 C++ 檔案中定義符號,請在定義中使用 extern "C"。
符號定義為靜態,但稍後在檔案外部被引用。
沒有定義靜態類成員。例如,應單獨定義下面類宣告中的成員變數 si:
#include <stdio.h>
struct X {
static int si;
};
// int X::si = 0; // uncomment this line to resolve
void main()
{
X *px = new X[2];
printf("\n%d",px[0].si); // LNK2019
}
也可能由於為 Visual Studio .NET 2003 進行的一致性工作生成此錯誤:模板友元和專用化。在 Visual Studio .NET 2003 中,必須定義宣告新的非模板函式的友元宣告。
要使程式碼在 Visual C++ 的 Visual Studio .NET 2003 和 Visual Studio .NET 版本中均有效,請顯式指定友元函式的模板引數列表。
// LNK2019.cpp
// LNK2019 expected
template<class T>
void f(T)
{
}
template<class T>
struct S
{
friend void f(T);
// Try the folowing line instead:
// friend void f<T>(T);
};
int main()
{
S<int> s;
f(1); // unresolved external
}
/VERBOSE 連結器選項幫助您檢視連結器引用的檔案。DUMPBIN 實用工具的 /EXPORT 和 /SYMBOLS 選項還可以幫助您檢視 dll 和物件/庫檔案中定義的符號。
**********************************************************************************************************