我正在针对一些旧式第三方库构建应用程序,并且在链接阶段遇到问题。 我正在尝试使用Visual Studio 9进行编译。我的编译命令是:
1 2 3
| 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 |
该代码可以干净地编译。 链接命令是:
1 2 3 4 5 6
| 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 |
我得到的错误是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| 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中的真正痛苦。
如果您仍然希望使用VS2008(或将来)来编译项目,我建议使用二进制编辑器来查看有问题的mainapp.obj对象文件。
这是我的一个小项目的示例。
zdbException.obj包含以下摘录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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中引用的功能。
在MSDN上检查以下内容:
-
/ MD使您的应用程序使用运行库的特定于多线程和DLL的版本。
-
/ MT使您的应用程序使用运行时库的多线程静态版本。
注意:" ...,以便链接程序将使用LIBCMT.lib解析外部符号"
因此,您将需要一组不同的库。
我如何找到要链接的库:
找到一个确实链接的配置,然后添加/ verbose选项。
将输出通过管道传输到文本文件。
尝试不链接的配置。
在步骤2的详细输出中查找未解析的符号(在您的情况下为" _declspec(dllimport)public:void thiscall std :: locale :: facet :: Register(void)"),然后找到使用的库。
将这些库添加到要链接的库列表中。
老套子,但对我有用。
一月
在尝试使这些东西在VS 2008下编译之后,我尝试了VS的早期版本-2005带有警告,而2003才起作用。我仔细检查了链接,找不到任何问题,所以我只是找不到它,或者那不是问题。
因此,重申一下,降级到VS 2003已对其进行了修复。