locked
FAQ:2.8 为什么会出现LNK2019错误:无法解析的外部符号“symbol”? RRS feed

  • 问题

  • 2.8为什么会出现LNK2019错误:无法解析的外部符号“symbol”?
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    2011年2月28日 2:53

答案

  • 这是最易混淆的错误信息之一,每个VC++程序员会经常性的遇到这个问题。我们先解释一些概念。

    A.      什么是“符号”

    总而言之,一个符号就是一个名字。它可以是一个变量的名字,一个函数的名字,一个类的名字,一个定义类型的名字,或是除了这些以外任何一个属于C++语言的名字或符号。它是用户自己定义的或是由依赖库引进的(另一个用户定义的)。

    B.      什么是外部

    VC++中,每一个资源文件(.cpp .c 等等)都被看做是一个编译单元,编译器每次编译一个单元,并产生当前编译单元的一个目标文件(.obj)。(注意:这个资源文件包含的所有头文件都会进行预处理并且被认为是这个编译单元的一部分)在这个编译单元的所有的东西都被认为是内部的,除此之外的都被认为是外部的。在C++中,您可以通过使用关键字来引用这些外部变量,这些关键字有extern_declspecdllimport)等等。

    C.      什么是解析”

    解析是链接阶段的术语。在链接时,链接器在内部找不到那些在目标文件中的变量的定义就会到外部去寻找。这个搜索范围包括:

    ·      在编译阶段产生的所有目标文件;

    ·      应用程序显式或隐式加载的所有依赖库;

    这个搜索过程就叫作解析

    D.      最后,什么是无法解析的外部符号

    如果链接器在外部找不到在内部没有定义的符号的定义,它就会报一个没有解决的外部变量的错误。

    E.       可能引起LNK2019错误的原因:没有解决的外部变量。

    我们已经知道当链接器找不到外部变量的定义就会报这个错误,因此引起这个错误的可能原因可以归纳如下:

    a  定义已经存在

                      例如:如果我们在a.cpp文件中定义了一个叫foo的函数:

            int foo()

    {

                             return 0;

    }

     b.cpp文件中,我们想调用函数foo,因此我们加了void foo();

                    作为函数声明,并且在另一个叫bar()的函数体中调用它。

    void bar()

    {

                           foo();

    }

    现在,当你生成这段代码是就会出现LNK2019的错误,说foo是一个没有解决的外部变量。在这种情况下,我们在a.cpp中定义了foo()函数,但是这个函数和我们调用的foo()函数不一样(返回值不一样)。这就是已经存在定义的一个例子。

     

    b)没有定义

    如果我们想调用在库文件中的一些函数,但是没有把这个库导入您的工程的additional dependency list 项中(设置顺序: Project | Properties | Configuration Properties | Linker | Input | Additional Dependency)。这样链接器就会报LNK2019错误,因为在当前的搜索范围内不存在相应的定义

     

     

    相关英文论坛的帖子:

    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/66f3eaaa-0842-469e-ab2b-1bb2d2f99d50
    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/a58f8683-370c-4543-98a4-d9d92fa3e8ff


    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    2011年2月28日 2:54