Visual Studio 如何删除警告LNK4217和LNK4049

kdfy810k  于 2023-03-03  发布在  其他
关注(0)|答案(6)|浏览(458)

链接步骤中出现警告。这些警告仅在发布模式下出现。
我的程序由两部分组成:生成.lib的库和使用该库的可执行文件。
当我构建库时,没有警告。但是当我构建可执行文件时,在链接上有警告LNK4217和LNK4049。例如:

3>DaemonCommon.lib(Exception.obj) : warning LNK4217: locally defined symbol ??0exception@std@@QAE@ABQBD@Z (public: __thiscall std::exception::exception(char const * const &)) imported in function "public: __thiscall std::bad_alloc::bad_alloc(char const *)" (??0bad_alloc@std@@QAE@PBD@Z)
3>DaemonCommon.lib(CommAnetoException.obj) : warning LNK4217: locally defined symbol ??0exception@std@@QAE@ABQBD@Z (public: __thiscall std::exception::exception(char const * const &)) imported in function "public: __thiscall std::bad_alloc::bad_alloc(char const *)" (??0bad_alloc@std@@QAE@PBD@Z)

我在MSDN上读到过,这些警告可能是由__declspec(dllimport)声明引起的.但是,在我的库的类中,我没有这样声明.例如,下面是我的类Exception:

#ifndef _EXCEPTION_HPP__
#define _EXCEPTION_HPP__

#include <string>

namespace Exception
{
    class Exception  
    {
    public:
        // Constructor by default
        Exception();

        // Constructor parametrized
        Exception(std::string& strMessage);

        // Get the message of the exception
        virtual std::string getMessage() const;

        // Destructor
        virtual ~Exception();

    protected:

        // String containing the message of the exception
        std::string mStrMessage;
    };
}

#endif

有人能告诉我为什么会出现这些警告以及如何删除它们吗?

sshcrbum

sshcrbum1#

这是由__declspec(import) * 引起的符号上提到的“进口”*,例如public: __thiscall std::exception::exception(char const * const &)上。这可能是由于运行时选择的编译器选项之间不匹配造成的(/MT(静态多线程运行时)与/MD(动态运行时))和预处理器选项(_DLL define)。特别是当你用/MT(或调试配置中的/MTd)编译时,这些警告会出现,但是_DLL不知何故被定义了。
因此,请确保在不使用/MD编译时没有定义_DLL
同样重要的是,要为与可执行文件相同的运行时编译所有库,因此请检查运行时选择是否与所有项目匹配,以及您是否链接了任何第三方库的适当版本。

6jjcrrmo

6jjcrrmo2#

这与OP的问题无关,但我也看到过在本地库中链接到可执行文件时出现LNK4217,其中没有运行时库不匹配。
某些库在构建为静态库时需要预处理器定义(无论使用静态运行时还是动态运行时)。例如,libzmq(0MQ)要求在构建静态库时定义符号ZMQ_STATIC。否则,在将库链接到可执行文件时将得到LN2417。

qcbq4gxm

qcbq4gxm3#

  • *__declspec(dllexport)/__declspec(dllimport)**不匹配也可能是由于标头定义的函数/类造成的。

例如:
您正在构建一个共享库(. dll),它混合使用标头定义/"仅"函数/类和链接函数/类(如果没有特定的接口文件,则在编译共享库时需要使用**__declspec(dllexport),在使用共享库时需要使用__declspec(dllimport))。
一个常见的错误是为实际上仅包含头文件的部分定义
__declspec(dllexport)/__declspec(dllimport)**,因此这些部分不是编译后的库本身的一部分。

bqucvtff

bqucvtff4#

Russ Keldorph提供的一些info,说明declspec(dllimport)实际上是做什么的(建议使用/QSimplicit-import-开关)。

acruukt9

acruukt95#

检查在动态库(.dll)配置的Visual Studio项目中是否错误地使用了__declspec(dllimport)而不是__declspec(dllexport)

pobjuy32

pobjuy326#

当我使用$〈TARGET_OBJECTS:mylib〉将cmake OBJECT库 mylib 链接到其他代码时,我收到了同样的警告。
我通过使用/Zl(省略默认库名称)编译选项构建OBJECT库来解决这个问题。

相关问题