How to delete warnings LNK4217 and LNK4049

2020-07-01 05:09发布

问题:

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.

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:

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:

#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 ?

回答1:

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 (_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.



回答2:

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.



回答3:

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



回答4:

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.



回答5:

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