无法解析 typeinfo 和 dynamic_cast 外部

unresolved external to typeinfo and dynamic_cast

提问人:Massimo Castrioto 提问时间:10/26/2017 最后编辑:Massimo Castrioto 更新时间:12/9/2017 访问量:1230

问:

我遇到的问题与这里讨论的问题非常相似:g++ 对 typeinfo 的未定义引用

即便如此,我相信我没有同样的问题,而那个 topi 的答案并没有真正帮助我。 我所拥有的是:

class Base
{
    virtual ~Base() {}
    virtual void foo() = 0;
    // some other pure virtual behaviors
};

class Derived : public Base
{
    void foo() {/* do stuff */}
    // override for all other virtual behaviors
};

然后在不同的功能中我有:

void bar( Base * base )
{
    Derived * derived = dynamic_cast<Derived *>(base);
}

void foobar( const Base & base1, const Base & base2 )
{
    if ( typeid(base1) == typeid(base2) )
        /* do something */;
}

因此,我确定该函数要么是纯虚拟的,要么是定义的(即使对象永远不可能是 Base)。这应该不会产生任何问题,并且与引用的不同 讨论,因为我确定我覆盖了虚拟功能。 即便如此,当使用 clang++ 进行编译时,当在 Derived 上使用时,它会为 typeid 和 dynamic_cast 发出未解析的外部函数,而对于从 Base 继承的其他类则不会这样做,并且会覆盖相同的 foo 行为。 为什么会这样做?

这里是错误:

error LNK2019: unresolved external symbol __imp___RTDynamicCast
error LNK2019: unresolved external symbol __imp___RTtypeid

我只是错过了一些愚蠢的东西,还是误解了这些错误?

编辑

我意识到我首先给出的代码示例不够描述:

class Base
{
public:
    virtual ~Base() {}
};

class Interface : public Base
{
public:
    virtual void foo() = 0;
    // some other pure virtual behaviors
};

class Derived : public Interface
{
public:
    void foo() {/* do stuff */}
    // override for all other virtual behaviors
};

void bar()
{
    Base * base = new Derived;
    Interface * interface = dynamic_cast<Interface *>(base);
    interface->foo()
}

更适合我想做的事情。

C 继承 clang++ unresolved-external

评论

0赞 JojOatXGME 10/26/2017
如果您使用的是 C++11 或更高版本,则可以在重写函数的声明中使用关键字重写。这样可以确保您不会错过函数原型中的一些细节。它看起来像这样:.void foo() override {...}
0赞 Massimo Castrioto 10/26/2017
在 Visual Studio 中编译和工作都很好。
0赞 RbMm 10/26/2017
您只需要在定义此符号的位置添加 lib 文件。例如msvcurt.lib
0赞 Massimo Castrioto 10/26/2017
@JojOatXGME感谢您的提示,但我已经知道了。不幸的是,我不能在这个项目中使用 c++11。
0赞 RbMm 10/26/2017
您自己使用 (内部调用 ) 和 (内部调用 )。因此,您需要使用 lib 文件,其中定义了此符号。 或。您的目标平台是 x64 吗?typeid__imp___RTtypeiddynamic_cast__imp___RTDynamicCast msvcurt.libvcruntime.lib

答:

1赞 RbMm 10/26/2017 #1

当你在代码中使用编译器内部生成指令时(这个不是针对 x86 平台,针对 x86 会调用)。当您使用编译器生成时(在 x86 平台上将是 )。当您开始链接时 - 链接器视图,在代码中使用了 2 个符号: 并且 - 他在您作为输入传递给他的所有 obj 和 lib 文件中搜索它,但找不到。结果并给你错误dynamic_cast<Derived *>(base);call [__imp___RTDynamicCast][__imp____RTDynamicCast]typeid(base1) == typeid(base2)call [__imp___RTtypeid]call [__imp____RTtypeid]__imp___RTDynamicCast__imp___RTtypeidLNK2019: unresolved external symbol

您需要搜索您的 CRT LIB 文件 - 它正好包含此字符串 - 并且 - 因为存在许多不同的 CRT 版本 - 不可能说哪个 lib 将包含此符号。说这可以是 或 .可能在 .您需要的所有内容 - 将此库之一添加到链接器输入。他找到了这个符号__imp____RTtypeid__imp___RTDynamicCastmsvcurt[d].libvcruntime[d].libmsvcrt.lib

评论

0赞 Massimo Castrioto 10/26/2017
你说的有道理,但现在我正在尝试将 vcruntime.lib 或 msvcurt.lib 添加到链接器输出中,发生的情况是它为其他一些函数找到了更多定义,例如: libvcruntime.lib(std_type_info.obj) : 错误 LNK2005:__std_type_info_compare已在 vcruntime.lib(VCRUNTIME140_APP.dll) 中定义
0赞 RbMm 10/26/2017
@MassimoCastrioto - 这是绝对正常的 - 2 个库冲突。您只需要使用一个.从默认库中删除libvcruntime.lib
0赞 RbMm 10/26/2017
@MassimoCastrioto - 您需要在链接器选项中使用,或者根本不需要使用,并直接添加或添加到链接器。只能使用一个 CRT 库/NODEFAULTLIB:libvcruntime.lib/NODEFAULTLIBmsvcurt.libvcruntime.lib
0赞 RbMm 10/26/2017
@MassimoCastrioto - 我尝试解释非常基本和明显的事情 - 每个使用的符号都必须在某个地方定义一次。 不包含您需要的所有符号。思考或包含所有符号。但是,当您一次使用 2+ 个 CRT 库时 - 多个库中存在许多符号 - 链接器根本不知道 - 哪个使用并给您错误LNK2005 - 符号已经定义。如果理解这一点 - 很容易解决问题libvcruntime.libvcruntime.libmsvcurt.lib
0赞 Massimo Castrioto 10/26/2017
我明白了,我不明白的是,为什么我必须告诉链接器默认不要链接库vcruntime.lib,然后手动传递同一个库?如果编译器默认已经链接了库,为什么它缺少符号?
1赞 Paul A. Bristow 12/9/2017 #2

我在Visual Studio和CodeBlocks上使用Clang 5.0平台工具集LLVM-VS2014时遇到了这个问题。

我添加了msvcrt.lib以提供缺少的.__imp____RTDynamicCast

评论

0赞 Paul A. Bristow 12/10/2017
在 Codeblocks 和 Visual Studio 平台上按预期链接和运行(相同的时间,所以可能相同的 asm/exe 代码?
0赞 Raul 12/7/2023 #3

我遇到了类似的问题,原来我只是没有在CMake依赖项列表中指定动态库。