当前位置:  开发笔记 > 编程语言 > 正文

编译引用STLport-5.1.4和VC++ 2008的应用程序时出现LNK2001错误

如何解决《编译引用STLport-5.1.4和VC++2008的应用程序时出现LNK2001错误》经验,为你挑选了1个好方法。

我为这篇长篇文章提前道歉...

当我们在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   

将链接和可执行项目链接到作为库项目的依赖项时会发生这种情况.奇怪的是,在链接库项目本身时不会发生这种情况.有任何想法吗?



1> Aaron..:

正如其他答案中所提到的,这是一个链接器错误,可能是库和使用不同选项编译的应用程序的结果.有一些解决这个问题的解决方案(目前已选择其中一个作为选择的答案).这些解决方案有效.但是,有一些工具可以使您的搜索更容易.

对于初学者来说,理解装饰名称会有所帮助.在所有的垃圾,你会认识一些事情:在你的函数的名称,命名空间,一些类类型所使用.它们周围的所有字符对编译器都有意义,但是您不需要编译器告诉您它们是什么.

输入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以使其编译.正如我所描述的那样,我正在追踪这个问题.

我希望这有助于某人解决这个问题!

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有