C++ 如何删除警告 LNK4217 和 LNK4049

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6979491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 21:04:15  来源:igfitidea点击:

How to delete warnings LNK4217 and LNK4049

c++visual-studiovisual-studio-2010warnings

提问by Cedekasme

I have warnings on the link step. These warnings appear only in release mode.

我在链接步骤上有警告。这些警告仅在发布模式下出现。

My program is composed of two parts: a library which generates a .lib and an executable which uses this library.

我的程序由两部分组成:一个生成 .lib 的库和一个使用该库的可执行文件。

When I build the library I have no warnings. But when I build my executable, on the link I have warnings LNK4217 and LNK4049. For example:

当我构建库时,我没有警告。但是当我构建我的可执行文件时,在链接上我有警告 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)

I have read in the MSDN, these warnings may be caused by the declaration of __declspec(dllimport). But, in my classes of my lib, I haven't things declared like this. For example, here is my class Exception:

我在 MSDN 中读过,这些警告可能是由 __declspec(dllimport) 的声明引起的。但是,在我的 lib 类中,我没有像这样声明的东西。例如,这是我的类异常:

#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

Can somebody tell me why these warnings appear and how to delete them ?

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

回答by Jan Hudec

It's caused by __declspec(import)on the symbols mentioned as "imported", ie. on public: __thiscall std::exception::exception(char const * const &). That may be caused by mismatch between compiler option for runtime selection (/MT(static multi-threaded runtime) v.s. /MD(dynamic runtime)) and the preprocessor options (_DLLdefine). In particular those warnings would appear if you compile with /MT(or /MTdin debug configuration), but _DLLsomehow got defined.

它是由__declspec(import)提到为“导入”的符号引起的,即。上public: __thiscall std::exception::exception(char const * const &)。这可能是由于运行时选择的编译器选项(/MT(静态多线程运行时)与/MD(动态运行时))与预处理器选项(_DLL定义)之间的不匹配造成的。特别是,如果您使用/MT(或/MTd在调试配置中)进行编译,则会出现这些警告,但_DLL不知何故已被定义。

So make sure you are not defining _DLLwhen not compiling with /MD.

因此,请确保_DLL在不使用/MD.

It is also important to compile all libraries for the same runtime as the executable, so check that the runtime selection matches for all projects and that you are linking appropriate version of any third-party libraries.

为与可执行文件相同的运行时编译所有库也很重要,因此请检查运行时选择是否与所有项目匹配,并且您正在链接任何第三方库的适当版本。

回答by Oliver Zendel

The mismatch of __declspec(dllexport)/__declspec(dllimport)can also happen due to header-defined functions/classes.

__declspec(dllexport)/__declspec(dllimport)的不匹配也可能由于头定义的函数/类而发生。

For example:

例如:

You are building a shared library (.dll) which uses a mixture of Header-Defined/"Only" functions/classes and linked functions/classes (without a specific interface file these need to use __declspec(dllexport)while compiling the shared lib and __declspec(dllimport)while using it).

您正在构建一个共享库 (.dll),它混合使用标头定义/“仅”函数/类和链接函数/类(没有特定的接口文件,这些需要在编译共享库时使用__declspec(dllexport)__declspec(dllimport)在使用它时)。

A common error is defining __declspec(dllexport)/__declspec(dllimport)for parts that are actually header-only and thus are not a part of the compiled lib itself.

一个常见的错误是定义__declspec(dllexport)/__declspec(dllimport)的部分实际上只是头文件,因此不是编译库本身的一部分。

回答by Doug

Some infofrom Russ Keldorph on what declspec(dllimport) actually does. (Suggests using the /QSimplicit-import-switch.)

一些信息从拉斯Keldorph什么declspec(dllimport的)实际执行。(建议使用/QSimplicit-import-开关。)

回答by zeus2

Check if erroneously used the __declspec(dllimport)instead of __declspec(dllexport)in a Dynamic Library(.dll) configured visual studio project.

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

回答by James Hirschorn

This is not relevant to the OP's issue, but I have also seen LNK4217 when linking in a local library to an executable, where there is no runtime library mismatch.

这与 OP 的问题无关,但我在本地库中链接到可执行文件时也看到了 LNK4217,其中没有运行时库不匹配。

Some libraries require a preprocessor definition when building them as static (regardless of whether static or dynamic runtime is used). For example, libzmq (0MQ) requires the symbol ZMQ_STATIC to be defined when building a static library. Otherwise, you will get LN2417 when linking your library into an executable.

一些库在将它们构建为静态时需要预处理器定义(无论是使用静态还是动态运行时)。例如,libzmq (0MQ) 需要在构建静态库时定义符号 ZMQ_STATIC。否则,将库链接到可执行文件时,您将获得 LN2417。