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

时间:2008-11-04 09:53:08

标签: c++ visual-studio-2008 visual-c++ linker stlport

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

当我们在VS Menu>下列出STLPort包含和库目录时,我曾经能够构建我们的VC ++解决方案(我们在VS 2008上)。工具>选项> VC ++目录>包含和库文件的目录。但是,我们希望转换到完全依赖.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<char,class stlp_std::char_traits<char> > &,class MyOtherClass &,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > &)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<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &,long,enum MyClass::MessageType,int,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &)" (?myFunction@MyClass@@SAXABV?$basic_string@DV?$char_traits@D@stlp_std@@V?$allocator@D@2@@stlp_std@@000JW4MessageType@1@H0@Z)  MyLibrary.lib   

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

6 个答案:

答案 0 :(得分:5)

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

首先,了解装饰名称会有所帮助。在所有垃圾中,你会发现一些事情:你正在使用的你的功能名称命名空间,一些类类型。它们周围的所有字符对编译器来说都意味着什么,但是你不需要编译器来告诉你它们是什么。

  

输入undname.exe:

     
      undname.exe&lt; decoratedname&gt;      
      
  • 是一个简单的命令行程序,位于VS bin目录中。
  •   
  • 将装饰名称作为第一个参数。
  •   
  • 输出符号的人类可读格式。
  •   

有了这些知识,你现在可以继续寻找错误创造符号的合理候选人。

首先,您可以在其他地方建议的十六进制编辑器中编辑库。但是,有一种更容易找到符号的方法。

  

输入dumpbin.exe:

     
      dumpbin.exe&lt; switches&gt; &lt;库名称&gt;      
      
  • 是一个简单的命令行程序,位于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函数),我们可以另外为该名称grep输出,但在这种情况下,我们可以从列表中选择它。这是我们转向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 才能进行编译。我正如我所描述的那样跟踪这个问题。

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

答案 1 :(得分:3)

Raymond Chen最近在The Old New Thing谈到了这个问题 - 这些问题的一个原因是该库是使用一组开关编译的,但您的应用程序使用的是另一组。你要做的是:

获取链接器正在查找的确切符号。这将是一个可怕的错误名称。 使用十六进制编辑器(IIRC,Visual Studio将执行此操作)来查看要链接到的.lib文件。 找到几乎是链接器所寻找的符号,但并不完全。 鉴于符号的不同,尝试找出哪些命令行开关会有所帮助。 祝你好运 - 对于那些不习惯这类问题的人来说,解决方案可能需要数天才能搞清楚(!)

答案 2 :(得分:1)

这些链接错误表明您的应用程序中的某些类尚未使用STLPort编译或已从构建中省略。他们并不暗示您没有链接STLport。

我的猜测是:

  • MyClass的构建设置以某种方式覆盖了包含路径的项目范围设置,因此使用默认的C ++ STL实现而不是STLport构建MyClass。这应该很容易检查 - 对目标文件运行dumpbin并检查其中的函数是否引用stlp_ *命名空间中的标准库。如果不是,编译器可能没有选择正确的包含路径。我还要看看IDE正在调用编译器的命令行。这些也可以通过C / C ++配置属性查看。
  • 正如其他海报也提到的那样,MyClass有可能不会被构建,但这应该很容易检查。

答案 3 :(得分:1)

您必须配置STL端口才能使用本机IOStream实现。

您还有使用STLPort的具体原因吗?除非您尝试创建跨平台应用程序,否则建议使用默认的STL实现 - 即使在大多数情况下也不需要它。

答案 4 :(得分:0)

这是一个链接错误。它与您的包含路径无关。

您忘记将MyClass.cpp添加到项目中,或忘记定义这两个函数。

“链接”库项目时未发生错误的原因是库项目未链接。它们只是一堆由LIB程序放在一起存放到库文件中的OBJ。

答案 5 :(得分:0)

将库名添加到要链接的其他库列表中。对不起,我不是在VS的最新版本面前知道确切的位置。

相关问题