如何删除警告 LNK4217 和 LNK4049
我对链接步骤有警告。这些警告仅在发布模式下出现。
我的程序由两部分组成:生成 .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)的声明引起的。但是,在我的库的类中,我没有这样声明的东西。例如,这是我的类异常:
#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
有人可以告诉我为什么会出现这些警告以及如何删除它们吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这是由
__declspec(import)
在提到“导入”的符号上引起的,即。在public: __thiscall std::exception::exception(char const * const &)
上。这可能是由于运行时选择的编译器选项(/MT
(静态多线程运行时)与/MD
(动态运行时))和预处理器选项(<代码>_DLL定义)。特别是,如果您使用/MT
(或调试配置中的/MTd
)进行编译,但_DLL
以某种方式被定义,则会出现这些警告。因此,请确保在不使用
/MD
进行编译时未定义_DLL
。将所有库编译为与可执行文件相同的运行时也很重要,因此请检查运行时选择是否与所有项目匹配,以及您是否链接了任何第三方库的适当版本。
It's caused by
__declspec(import)
on the symbols mentioned as "imported", ie. onpublic: __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 (_DLL
define). In particular those warnings would appear if you compile with/MT
(or/MTd
in debug configuration), but_DLL
somehow got defined.So make sure you are not defining
_DLL
when not compiling with/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.
这与OP的问题无关,但我在将本地库链接到可执行文件时也看到了LNK4217,其中没有运行时库不匹配。
某些库在将其构建为静态时需要预处理器定义(无论使用静态还是动态运行时)。例如,libzmq (0MQ) 需要在构建静态库时定义符号 ZMQ_STATIC。否则,在将库链接到可执行文件时,您将得到 LN2417。
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.
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.
由于标头定义的函数/类,也可能会发生 __declspec(dllexport)/__declspec(dllimport) 不匹配的情况。
例如:
您正在构建一个共享库(.dll),它混合使用标头定义/“仅”函数/类和链接函数/类(没有特定的接口文件,这些需要使用 __declspec(dllexport) 在编译共享库时和 __declspec(dllimport) 在使用它时)。
一个常见的错误是为实际上仅包含头文件的部分定义 __declspec(dllexport)/__declspec(dllimport) ,因此不属于已编译库本身的一部分。
The mismatch of __declspec(dllexport)/__declspec(dllimport) can also happen due to header-defined functions/classes.
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).
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.
一些来自 Russ Keldoph 的信息,了解 declspec(dllimport) 的实际作用。 (建议使用
/QSimplicit-import-
开关。)Some info from Russ Keldorph on what declspec(dllimport) actually does. (Suggests using the
/QSimplicit-import-
switch.)检查在动态库 (.dll) 配置的 Visual Studio 项目中是否错误地使用了
__declspec(dllimport)
而不是__declspec(dllexport)
。Check if erroneously used the
__declspec(dllimport)
instead of__declspec(dllexport)
in a Dynamic Library (.dll) configured visual studio project.当使用 $mylib> 将 cmake OBJECT 库 mylib 链接到其他代码时,我收到了相同的警告。
我通过使用 /Zl(省略默认库名称)编译选项构建 OBJECT 库解决了这个问题。
I got the same warnings when linking a cmake OBJECT library mylib into other code with $<TARGET_OBJECTS:mylib>.
I solved this by building the OBJECT library with the /Zl (omit default library name) compile option.