簡體   English   中英

C ++鏈接器未解析的外部符號

[英]C++ linker unresolved external symbols

我正在針對一些舊式第三方庫構建應用程序,並且在鏈接階段遇到問題。 我正在嘗試使用Visual Studio 9進行編譯。我的編譯命令是:

cl -DNT40 -DPOMDLL -DCRTAPI1=_cdecl
-DCRTAPI2=cdecl -D_WIN32 -DWIN32 -DWIN32_LEAN_AND_MEAN -DWNT -DBYPASS_FLEX -D_INTEL=1 -DIPLIB=none -I. -I"D:\src\include" -I"C:\Program Files\Microsoft Visual Studio
9.0\VC\include" -c -nologo -EHsc -W1 -Ox -Oy- -MD mymain.c

代碼可以干凈地編譯。 鏈接命令是:

link -debug -nologo -machine:IX86
-verbose:lib -subsystem:console mymain.obj wsock32.lib advapi32.lib
msvcrt.lib oldnames.lib kernel32.lib
winmm.lib [snip large list of
dependencies] D:\src\lib\app_main.obj
-out:mymain.exe

我得到的錯誤是:

app_main.obj : error LNK2019:
unresolved external symbol
"_\_declspec(dllimport) public: void
__thiscall std::locale::facet::_Register(void)"
(__imp_?_Register@facet@locale@std@@QAEXXZ)
referenced in function "class
std::ctype<char> const & __cdecl
std::use_facet<class std::ctype<char>
(class std::locale const &)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@@Z)

app_main.obj : error LNK2019:
unresolved external symbol
"__declspec(dllimport)  public: static
unsigned int __cdecl
std::ctype<char>::_Getcat(class
std::locale::facet const * *)"
(__imp_?_Getcat@?$ctype@D@std@@SAIPAPBVfacet@locale@2@@Z)
referenced in function "class
std::ctype<char> const & __cdecl
std::use_facet<class std::ctype<char>
(class std::locale const &)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@@Z)

app_main.obj : error LNK2019:
unresolved external symbol
"__declspec(dllimport)  public: static
unsigned int __cdecl
std::ctype<unsigned
short>::_Getcat(class
std::locale::facet const * *)"
(__imp_?_Getcat@?$ctype@G@std@@SAIPAPBVfacet@locale@2@@Z)
referenced in function "class
std::ctype<unsigned short> const &
__cdecl std::use_facet<class std::ctype<unsigned short> >(class
std::locale const &)"
(??$use_facet@V?$ctype@G@std@@@std@@YAABV?$ctype@G@0@ABVlocale@0@@Z)

mymain.exe : fatal error LNK1120: 3
unresolved externals

請注意,這些錯誤來自舊代碼,而不是我的代碼-app_main.obj是舊代碼的一部分,而mymain.c是我的源代碼。 我已經進行了一些搜索,我讀到的內容表明,這種類型的錯誤是由於我的代碼與要鏈接的庫之間的-MD開關不匹配而引起的。 由於我要處理遺留代碼,因此解決方案必須來自我的環境。 自完成C ++工作以來已經很長時間了,而自從使用Visual Studio以來已經更長了,所以我希望這只是我的一些無知。 關於如何解決這些問題的任何想法?

這些是標准庫參考。 確保所有庫(包括標准庫)都使用相同的鏈接。 例如,在動態鏈接標准庫時,您不能靜態鏈接。 使用的線程模型也是如此。 請特別注意您和第三方庫使用相同的鏈接選項。

這可能是* ss的真正痛苦。

MSDN上檢查一下:

  • / MD使您的應用程序使用運行庫的特定於多線程和DLL的版本。
  • / MT使您的應用程序使用運行庫的多線程靜態版本。

注意:“ ...,以便鏈接程序將使用LIBCMT.lib解析外部符號”

因此,您將需要一組不同的庫。

我如何找出要鏈接的庫:

  1. 查找一個確實鏈接的配置,然后添加/ verbose選項。
  2. 將輸出通過管道傳輸到文本文件。
  3. 請嘗試鏈接的配置。
  4. 在步驟2的詳細輸出中查找未解析的符號(在您的情況下為“ _declspec(dllimport)public:void thiscall std :: locale :: facet :: Register(void)”),然后找到使用的庫。
  5. 將這些庫添加到要鏈接的庫列表中。

舊派但它的工作對我來說。

一月

如果您仍然希望使用VS2008(或將來)來編譯項目,我建議您使用二進制編輯器來查看有問題的對象文件mainapp.obj

這是我的一個小項目的示例。

zdbException.obj包含以下摘錄

DEFAULTLIB:"libc
pmtd" /DEFAULTLI
B:"uuid.lib" /DE
FAULTLIB:"uuid.l
ib" /include:?id
@?$num_put@DV?$o
streambuf_iterat
or@DU?$char_trai
ts@D@std@@@std@@
@std@@2V0locale@
2@A /include:?id
@?$numpunct@D@st
d@@2V0locale@2@A
 /DEFAULTLIB:"LI
BCMTD" /DEFAULTL
IB:"OLDNAMES" /E
DITANDCONTINUE 

注意條目/ DEFAULTLIB:“ LIBCMTD” 這表明目標文件是使用靜態c運行時多線程調試編譯的。

VS2008附帶的標准運行時庫中也有可能不推薦obj中引用的功能。

在嘗試使這些東西在VS 2008下編譯之后,我嘗試了VS的早期版本-2005帶有警告,而2003才起作用。 我仔細檢查了鏈接,找不到任何問題,所以我只是找不到它,或者那不是問題。

因此,重申一下,降級到VS 2003已對其進行了修復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM