我为这篇长篇文章提前道歉...
当我们在VS菜单>工具>选项> VC++目录>包含和包含文件的目录下列出STLPort包含和库目录时,我曾经能够构建我们的VC++解决方案(我们在VS 2008上).但是,我们希望转换到完全依赖.vcproj和.sln文件的构建过程.与VS选项不同,这些可以检查到源控制中,VS选项必须分别在每台开发PC上配置.我们通过将Include目录添加到每个项目的属性页>配置属性> C/C++>常规>其他包含目录和库目录到链接器>常规>其他库目录来处理大多数库的转换.
不幸的是,这种方法不适用于STLPort.我们在链接期间收到LNK2019和LNK2001错误:
Error 1 error LNK2019: unresolved external symbol "public: virtual bool __thiscall MyClass::myFunction(class stlp_std::basic_istream> &,class MyOtherClass &,class stlp_std::basic_string ,class stlp_std::allocator > &)const " (?myFunction@MyClass@@UBE_NAAV?$basic_istream@DV?$char_traits@D@stlp_std@@@stlp_std@@AAVSbprobScenarioData@@AAV?$basic_string@DV?$char_traits@D@stlp_std@@V?$allocator@D@2@@3@@Z) referenced in function _main MyLibrary.obj Error 5 error LNK2001: unresolved external symbol "public: static void __cdecl MyClass::myFunction(class stlp_std::basic_string ,class stlp_std::allocator > const &,class stlp_std::basic_string ,class stlp_std::allocator > const &,class stlp_std::basic_string ,class stlp_std::allocator > const &,class stlp_std::basic_string ,class stlp_std::allocator > const &,long,enum MyClass::MessageType,int,class stlp_std::basic_string ,class stlp_std::allocator > const &)" (?myFunction@MyClass@@SAXABV?$basic_string@DV?$char_traits@D@stlp_std@@V?$allocator@D@2@@stlp_std@@000JW4MessageType@1@H0@Z) MyLibrary.lib
将链接和可执行项目链接到作为库项目的依赖项时会发生这种情况.奇怪的是,在链接库项目本身时不会发生这种情况.有任何想法吗?
正如其他答案中所提到的,这是一个链接器错误,可能是库和使用不同选项编译的应用程序的结果.有一些解决这个问题的解决方案(目前已选择其中一个作为选择的答案).这些解决方案将有效.但是,有一些工具可以使您的搜索更容易.
对于初学者来说,理解装饰名称会有所帮助.在所有的垃圾,你会认识一些事情:在你的函数的名称,命名空间,一些类类型所使用.它们周围的所有字符对编译器都有意义,但是您不需要编译器告诉您它们是什么.
输入undname.exe:
undname.exe
是一个简单的命令行程序,位于VS bin目录中.
将装饰名称作为第一个参数.
输出符号的人类可读格式.
有了这些知识,您现在可以继续为错误创建的符号寻找合理的候选人.
首先,您可以在其他地方建议的十六进制编辑器中编辑库.但是,有一种更容易找到符号的方法.
输入dumpbin.exe:
dumpbin.exe<库名>
是一个简单的命令行程序,位于VS bin目录中.
采用一组开关和一个库来应用它们.
输出图书馆的信息
您将对您的问题感兴趣的开关是/ linkermember.还有许多其他开关可以为您提供非常有趣的信息,但是这一个将列出库中的所有符号.
在这一点上,一个小的命令行精明将为你服务.像grep这样的工具可以真正缩短你的工作周期,但你可以通过重定向到文件并使用记事本等来实现.
由于我没有您的代码或库,我将设计一个来自TinyXML的示例.
假设您的错误消息是这样的:
Error 1 error LNK2019: unresolved external symbol "public: unsigned char __cdecl TiXmlComment::Accept(bool,class TiXmlVisitor *) " (?Accept@TiXmlComment@@ZBE_NPAVTiXmlVisitor@@@Z) referenced in function _main MyLibrary.obj
确定这是TinyXML中的一个函数后,我可以开始寻找不匹配的符号.我将首先转储库的链接器.(请注意,开关是单数的,当我从内存中输入时,这总是会得到我!)
>dumpbin /linkermember tinyxml.lib Microsoft (R) COFF/PE Dumper Version 8.00.50727.762 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file tinyxml.lib File Type: LIBRARY Archive member name at 8: / 4992E7BC time/date Wed Feb 11 08:59:08 2009 uid gid 0 mode B402 size correct header end 859 public symbols 16292 ??$_Allocate@D@std@@YAPADIPAD@Z 16292 ??$_Char_traits_cat@U?$char_traits@D@std@@@std@@YA?AU_Secure_char_traits_tag@0@XZ 16292 ??$copy_s@U?$char_traits@D@std@@@_Traits_helper@std@@YAPADPADIPBDI@Z 16292 ??$copy_s@U?$char_traits@D@std@@@_Traits_helper@std@@YAPADPADIPBDIU_Secure_char_traits_tag@1@@Z 16292 ??$move_s@U?$char_traits@D@std@@@_Traits_helper@std@@YAPADPADIPBDI@Z 16292 ??$move_s@U?$char_traits@D@std@@@_Traits_helper@std@@YAPADPADIPBDIU_Secure_char_traits_tag@1@@Z 16292 ??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@@Z 16292 ??0?$_String_val@DV?$allocator@D@std@@@std@@IAE@V?$allocator@D@1@@Z 16292 ??0?$_String_val@DV?$allocator@D@std@@@std@@QAE@ABV01@@Z
这显然是无法阅读,但我们不必,我们知道我们正在寻找什么,所以我们只是寻找它.
>dumpbin /linkermember tinyxml.lib | grep Accept 529AE ?Accept@TiXmlComment@@UBE_NPAVTiXmlVisitor@@@Z 529AE ?Accept@TiXmlDeclaration@@UBE_NPAVTiXmlVisitor@@@Z 529AE ?Accept@TiXmlDocument@@UBE_NPAVTiXmlVisitor@@@Z 529AE ?Accept@TiXmlElement@@UBE_NPAVTiXmlVisitor@@@Z 529AE ?Accept@TiXmlText@@UBE_NPAVTiXmlVisitor@@@Z 529AE ?Accept@TiXmlUnknown@@UBE_NPAVTiXmlVisitor@@@Z 3 ?Accept@TiXmlComment@@UBE_NPAVTiXmlVisitor@@@Z 3 ?Accept@TiXmlDeclaration@@UBE_NPAVTiXmlVisitor@@@Z 3 ?Accept@TiXmlDocument@@UBE_NPAVTiXmlVisitor@@@Z 3 ?Accept@TiXmlElement@@UBE_NPAVTiXmlVisitor@@@Z 3 ?Accept@TiXmlText@@UBE_NPAVTiXmlVisitor@@@Z 3 ?Accept@TiXmlUnknown@@UBE_NPAVTiXmlVisitor@@@Z
这更容易阅读.看看我们的错误,我们正在寻找TiXmlComment的Accept函数.如果我们有很多匹配项(比如查看stl中的size函数),我们可以为该名称另外输出输出,但在这种情况下,我们可以从列表中选择它.这是我们转向undname的地方:
>undname ?Accept@TiXmlComment@@UBE_NPAVTiXmlVisitor@@@Z Microsoft (R) C++ Name Undecorator Copyright (C) Microsoft Corporation. All rights reserved. Undecoration of :- "?Accept@TiXmlComment@@UBE_NPAVTiXmlVisitor@@@Z" is :- "public: virtual bool __thiscall TiXmlComment::Accept(class TiXmlVisitor *)const "
因此,在这个例子中,我们的应用程序正在寻找一个返回unsigned char的函数,但是库有一个返回bool的函数.
这是一个人为的例子,但它说明了用于追踪问题的技术.您可能正在寻找一种typedef类型,根据您的选项设置不同.
我碰到的问题是time_t.在我使用的一些库中,time_t使用32位类型作为其内部表示的一部分.该库是使用较旧的编译器生成的,这是默认的.在VS 2005中,time_t默认使用64位类型.我不得不添加预处理器定义_USE_32BIT_TIME_T以使其编译.正如我所描述的那样,我正在追踪这个问题.
我希望这有助于某人解决这个问题!