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

发布于 2024-07-08 12:19:32 字数 2047 浏览 8 评论 0原文

我提前对这篇长篇文章表示歉意...

当我们在 VS 菜单 > 下列出 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   

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

I apologize in advance for the long post...

I used to be able to build our VC++ solutions (we're on VS 2008) when we listed the STLPort include and library directories under VS Menu > Tools > Options > VC++ Directories > Directories for Include and Library files. However, we wanted to transition to a build process that totally relies on .vcproj and .sln files. These can be checked into source control unlike VS Options which have to be configured on each development PC separately. We handled the transition for most libraries by adding the Include directories to each Project's Property Pages > Configuration Properties > C/C++ > General > Additional Include Directories, and Library directories to Linker > General > Additional Library Directories.

Unfortunately, this approach doesn't work for STLPort. We get LNK2019 and LNK2001 errors during linking:

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   

This happens while linking and executable project to dependencies which are library projects. Curiously, this does not happen while linking the library projects themselves. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

匿名的好友 2024-07-15 12:19:32

正如其他答案中提到的,这是一个链接器错误,可能是使用不同选项编译库和应用程序的结果。 已经有一些解决方案可以追踪这个问题(其中之一是当前选择的答案)。 这些解决方案将会发挥作用。 不过,有一些工具可以使您的搜索变得更加容易

对于初学者来说,了解修饰名称会有所帮助。 在所有这些垃圾中,您将认出一些东西:您正在使用的函数名称命名空间、一些类类型。 它们周围的所有这些字符对编译器都有一定的意义,但您不需要编译器告诉您它们是什么。

输入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 函数!),我们可以另外 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才能编译它。 我按照我所描述的方式准确地追踪了这个问题。

我希望这可以帮助有人解决这个问题!

As mentioned in other answers, this is a linker error and likely the result of the library and the application being compiled with different options. There are a few solutions on tracking this down already (one of them as the chosen answer, currently). These solutions will work. However, there are a few tools that will make your search much much easier.

For starters, understanding decorated names will help. Within all that garbage, you will recognise some things: The name of your function, namespaces, some class types you are using. All of those characters around them mean something to the compiler, but you don't need the compiler to tell you what they are.

Enter undname.exe:


undname.exe <decoratedname>

  • is a simple command line program that is in your VS bin directory.
  • takes the decorated name as it's first argument.
  • outputs a human readable format of the symbol.

Armed with that knowledge, you can now move on to finding a reasonable candidate for the mis-created symbol.

First off, you could edit your libraries in a hex editor, as suggested elsewhere. However, there is a much easier way to find the symbols.

Enter dumpbin.exe:


dumpbin.exe <switches> <library name>

  • is a simple command line program that is in your VS bin directory.
  • takes a set of switches and a library to apply them to.
  • outputs information from the library

The switch you will be interested in for your question is /linkermember. There are many other switches that can get you very interesting information, but this one will list out all the symbols in the library.

At this point, a little commandline savvy will serve you well. Tools like grep can really shorten your work-cycle, but you can get by with redirecting to a file and using notepad or the like.

Since I don't have your code or library, I'll contrive an example from TinyXML.

Assuming your error message was this:

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 

Having determined this is a function in the TinyXML, I can start looking for the mismatched symbol. I'll start by dumping the linkermembers of the library. (Notice the switch is singular, this always gets me when I type it from memory!)


>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

This is obviously too much to read, but we don't have to, we know what we're looking for, so we'll just look for it.


>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

That's much easier to read. Looking at our error, we're looking for the Accept Function of TiXmlComment. We could grep the output additionally for that name, if we had lots of matches (like looking at the size function in the stl!), but in this case, we can pick it out of the list. Here is where we turn to 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 "

So, in this example, our application is looking for a function which returns an unsigned char, but the library has a function returning a bool.

This is a contrived example, but it illustrates the technique to use to track down your issue. You are probably looking for a typedef type which is set differently based on your options.

The problem where I ran into this was with time_t. In some libraries I was using, the time_t used a 32-bit type as part of it's internal representation. This library was generated with an older compiler, where that was the default. In VS 2005, the time_t uses a 64-bit type by default. I had to add the preprocessor define _USE_32BIT_TIME_T to get it to compile. I tracked this issue down precisely as I have described.

I hope this helps someone solve this issue!

森末i 2024-07-15 12:19:32

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

获取链接器正在寻找的确切符号。 这将是一个可怕的、扭曲的名字。
使用十六进制编辑器(IIRC,Visual Studio 将执行此操作)查看要链接到的 .lib 文件。
找到几乎是链接器正在寻找的东西的符号,但又不完全是。
鉴于符号的差异,尝试找出哪些命令行开关有帮助。
祝你好运——对于不习惯此类问题的人来说,解决方案可能需要几天的时间才能弄清楚(!)

Raymond Chen recently talked about this at The Old New Thing-- one cause of these problems is that the library was compiled with one set of switches, but your app is using a different set. What you have to do is:

Get the exact symbol that the linker is looking for. It will be a horrible mangled name.
Use a hex editor (IIRC, Visual Studio will do this) to look at the .lib file you're linking to.
Find the symbol that's almost the thing the linker is looking for, but not quite.
Given the differences in the symbols, try to figure out what command line switches will help.
Good luck -- for people who aren't used to this sort of problem, the solution can take days to figure out (!)

浮世清欢 2024-07-15 12:19:32

这些链接错误表明您的应用程序中的某些类尚未使用 STLPort 进行编译,或者已在构建中被省略。 他们并不建议您不要链接到 STLport。

我的猜测是:

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

These link errors suggest that certain classes in your application either haven't been compiled using STLPort or have been omitted from the build. They do not suggest that you aren't linking against STLport.

My guesses would be that:

  • The build settings for MyClass somehow overwrite the project-wide setting for the include path and thus MyClass is being built using the default C++ STL implementation and not STLport. This should be easy to check - run dumpbin against the object file and check the functions in there reference the standard library in the stlp_* namespace or not. If not, it's likely that the compiler is not picking up the correct include path. I'd also have a look at the command line that the IDE is calling the compiler with. These can be viewed via the C/C++ Configuration properties as well.
  • As other posters also mentioned, there is a chance that MyClass isn't being built, but that should be very easy to check.
梦屿孤独相伴 2024-07-15 12:19:32

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

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

You have to configure STL port to use the native IOStreams implementation.

Also is there any specific reason you use STLPort? The default STL implementation is recommended unless you are trying to make a cross platform application - even then its not really needed in most cases.

×眷恋的温暖 2024-07-15 12:19:32

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

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

“链接”库项目时不会发生错误的原因是库项目未链接。 它们只是由 LIB 程序组合成库文件的一堆 OBJ。

This is a link error. It doesn't have to do with your include paths.

You either forgot to add MyClass.cpp to your project, or forgot to define those two functions.

The reason the error doesn't happen when "linking" library projects is that library projects are not linked. They are simply a bunch of OBJs that are put together by the LIB program into a library file.

如歌彻婉言 2024-07-15 12:19:32

将库名称添加到要链接的其他库的列表中。 抱歉,我没有使用最新版本的 VS,无法确切知道它的去向。

Add the library name to the list of additional libraries to link. Sorry I'm not in front of a recent version of VS to know exactly where it goes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文