【问题标题】:LNK2019 - Unresolved external symbolLNK2019 - 未解析的外部符号
【发布时间】:2014-11-07 14:45:25
【问题描述】:

我试图通过查看旧的问题和答案来找到解决此问题的方法,但我无法发现我的情况有什么问题。我收到以下错误:

Error 66 error LNK2019: unresolved external symbol "public: static class PhysicsBody *
__cdecl PhysicsBody::createBox(float,float,enum PhysicsBodyType,float)"
(?createBox@PhysicsBody@@SAPAV1@MMW4PhysicsBodyType@@M@Z) referenced in function
"public: __thiscall Enemy::Enemy(void)" (??0Enemy@@QAE@XZ)

奇怪的是,.H 和 .CPP 都存在代码文件,并且它们包含在解决方案中并正确编译。这是代码文件:

// Enemy.h
#pragma once

class Enemy {
public:
    Enemy();
private:
    PhysicsBody* m_body;
};

// Enemy.cpp
#include "Enemy.h"
#include "PhysicsBody.h"

Enemy::Enemy() {
    m_body = PhysicsBody::createBox(1.f, 1.f, PhysicsBodyType::Dynamic);
}

// PhysicsBody.h
#pragma once

enum PhysicsBodyType {
    Static, Dynamic, Kinematic
};

class PhysicsBody {
public:
    static PhysicsBody* createBox(float width, float height, PhysicsBodyType type, float mass = 1.f);
private:
    PhysicsBody();
};

// PhysicsBody.cpp
#include "PhysicsBody.h"

PhysicsBody::PhysicsBody() {

}

PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
    return new PhysicsBody();
}

(我在这里剪掉了一些不相关的代码。)

我已经浏览了数十次代码,但没有发现任何问题。我在整个项目中都有类似的代码,其他一切正常。出于某种原因,这个PhysicsBody 类会导致这些问题。我检查了它是否包含在项目/解决方案中,文件类型是 C/C++ 代码,它没有标记为内容,总体上它应该可以工作。

【问题讨论】:

  • 您在 Windows 上吗?你建立一个DLL? Enemy 和 PhysicsBody 是否在同一个模块中? (DLL 或 exe)?
  • 我在 Windows 上,没有构建 DLL,并且两者都在同一个项目中。 PhysicsBody 类中大约有 20 个方法,其中三个都给出了错误,上面代码中显示的只是一个示例。
  • 好的。我看到你在此期间解决了你的问题。在 Windows 上,我经常用来解决此类问题的工具是 Dependency walker dependencywalker.com。通常通过使用它,您会发现该类没有从它所在的 thr Dll 中导出(因此链接器理所当然地抱怨),或者导出函数的“损坏”名称与错误消息中的名称不同(这可能是由于链接到一个过时的 DLL 导出库)。这就是我问你是否在 Windows 上的原因。

标签: c++ unresolved-external


【解决方案1】:

这个问题很可能是由错误的 VS 项目文件引起的。我复制了 PhysicsBody.h / .cpp 文件的内容,删除了这两个文件,创建了新文件并粘贴了原始内容。所有代码都完全一样,现在可以运行了,所以我断定这是一个与 VS 相关的错误。

【讨论】:

    【解决方案2】:

    问题代码中的错误

    没有找到的函数是:

    PhysicsBody::createBox(float, float, enum PhysicsBodyType, float)
    

    定义的函数是:

    PhysicsBody::createBox(float, float, enum PhysicsBodyType)
    

    两个函数之间的参数数量不同。

    出现的问题:

    1. 哪个是正确的定义?
    2. 如何使用错误定义?
    3. 错误使用声明在哪里?

    您可能需要简单地重新编译所有内容。您可能需要查看 PhysicsBody 类的定义位置,因为它在两个地方定义。

    这个问题现在已经在问题中解决了。


    问题中的代码没有重大错误

    使用修改后问题中的代码(在Enemy.h 的开头添加了#include "PhysicsBody.h",因此可以独立编译标头),并忽略有关createBox 函数的未使用参数的警告,我可以编译并使用来自 GCC 4.9.1 的 g++ 和一个简单的 main() 链接代码:

    #include "Enemy.h"
    
    int main()
    {
        Enemy e;
        return 0;
    }
    

    这表明问题不在于您显示的代码,而在于您未显示的代码。请学习如何创建 MCVE (How to create a Minimal, Complete, and Verifiable Example?) 或 SSCCE (Short, Self-Contained, Correct Example) — 相同基本思想的两个名称和链接。

    请准确发布重现问题的最少代码。 (我创建了一个新的子目录,将 5 个源文件——两个头文件、两个实现文件和一个琐碎的main()——放入目录中,并从那里编译了一个生成文件。我建议你在你的 Windows 机器上做同样的事情。)

    如果您确认上面发布的代码加上我显示的main.cpp 确实(1)编译和(2)无法链接,从而重现问题,那么MSVC 中存在表面上的错误。我认为这不太可能,但更有趣的事情已经知道了。

    作为记录,我在 Mac OS X 10.9.4 Mavericks 上使用 GCC 4.9.1 和以下命令(显示警告消息)进行编译:

    $ g++ -O3 -g  -std=c++11 -Wall -Wextra    -c Enemy.cpp
    $ g++ -O3 -g  -std=c++11 -Wall -Wextra    -c PhysicsBody.cpp
    PhysicsBody.cpp:8:43: warning: unused parameter ‘width’ [-Wunused-parameter]
     PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
                                               ^
    PhysicsBody.cpp:8:56: warning: unused parameter ‘height’ [-Wunused-parameter]
     PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
                                                            ^
    PhysicsBody.cpp:8:80: warning: unused parameter ‘type’ [-Wunused-parameter]
     PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
                                                                                    ^
    PhysicsBody.cpp:8:92: warning: unused parameter ‘mass’ [-Wunused-parameter]
     PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
                                                                                                ^
    $ g++ -O3 -g  -std=c++11 -Wall -Wextra    -c main.cpp
    $ g++ -o main *.o
    $ ./main
    $ echo $?
    0
    $
    

    【讨论】:

    • 啊,丢失的浮点数是我的代码示例中的错字,我不小心复制粘贴了错误的函数重载。问题不存在。我试过重新编译代码,清理解决方案,重建......似乎没有任何帮助。
    猜你喜欢
    • 2013-06-01
    • 1970-01-01
    • 2022-01-06
    • 2014-09-19
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 2012-10-31
    相关资源
    最近更新 更多