Как удалить предупреждения LNK4217 и LNK4049 - PullRequest
17 голосов
/ 08 августа 2011

У меня есть предупреждения на шаге ссылки.Эти предупреждения появляются только в режиме выпуска.

Моя программа состоит из двух частей: библиотеки, которая генерирует .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

Может кто-нибудь сказать мне, почему появляются эти предупреждения и как их удалить?

Ответы [ 5 ]

22 голосов
/ 08 августа 2011

Это вызвано __declspec(import) на символах, упомянутых как "импортированные" , т.е.на public: __thiscall std::exception::exception(char const * const &).Это может быть вызвано несоответствием между опцией компилятора для выбора времени выполнения (/MT (статическая многопоточная среда выполнения) против /MD (динамическая среда выполнения)) и параметрами препроцессора (_DLL define).В частности, эти предупреждения будут появляться, если вы компилируете с /MT (или /MTd в конфигурации отладки), но _DLL каким-то образом определены.

Поэтому убедитесь, что вы не определяете _DLL, когда не компилируетес /MD.

Также важно скомпилировать все библиотеки для той же среды выполнения, что и для исполняемого файла, поэтому убедитесь, что выбор среды выполнения соответствует всем проектам и что вы связываете соответствующую версию любых сторонних библиотек..

1 голос
/ 17 апреля 2017

Некоторые информация от Расса Келдорфа о том, что фактически делает declspec (dllimport).(Предлагает использовать переключатель /QSimplicit-import-.)

1 голос
/ 18 января 2017

Несоответствие __declspec (dllexport) / __declspec (dllimport) также может произойти из-за определенных в заголовке функций / классов.

Например:

Вы создаете общую библиотеку (.dll), которая использует смесь функций / классов, определенных в заголовке / «Только», и связанных функций / классов (без специального файла интерфейса для них необходимо использовать __ declspec (dllexport) при компиляции разделяемой библиотеки и __declspec (dllimport) при ее использовании).

Распространенной ошибкой является определение __declspec (dllexport) / __declspec (dllimport) для частей, которые фактически являются только заголовками и, следовательно, не являются частью самой скомпилированной библиотеки.

0 голосов
/ 27 июля 2018

Проверьте, ошибочно ли используется __declspec(dllimport) вместо __declspec(dllexport) в Динамической библиотеке (.dll), настроенной для проекта Visual Studio.

0 голосов
/ 10 декабря 2015

Это не относится к проблеме OP, но я также видел LNK4217 при связывании в локальной библиотеке с исполняемым файлом, где нет несоответствия библиотеки времени выполнения.

Некоторые библиотеки требуют определения препроцессора при построении их как статического (независимо от того, используется ли статическое или динамическое время выполнения). Например, libzmq (0MQ) требует, чтобы символ ZMQ_STATIC был определен при создании статической библиотеки. В противном случае вы получите LN2417 при связывании вашей библиотеки в исполняемый файл.

...