2011-08-08 19 views
11

Tengo advertencias en el paso del enlace. Estas advertencias aparecen solo en modo de lanzamiento.Cómo eliminar las advertencias LNK4217 y LNK4049

Mi programa se compone de dos partes: una biblioteca que genera un .lib y un ejecutable que utiliza esta biblioteca.

Cuando construyo la biblioteca no tengo advertencias. Pero cuando construyo mi ejecutable, en el enlace tengo advertencias LNK4217 y LNK4049. Por ejemplo:

3>DaemonCommon.lib(Exception.obj) : warning LNK4217: locally defined symbol [email protected]@@[email protected]@Z (public: __thiscall std::exception::exception(char const * const &)) imported in function "public: __thiscall std::bad_alloc::bad_alloc(char const *)" ([email protected]@@[email protected]@Z) 
3>DaemonCommon.lib(CommAnetoException.obj) : warning LNK4217: locally defined symbol [email protected]@@[email protected]@Z (public: __thiscall std::exception::exception(char const * const &)) imported in function "public: __thiscall std::bad_alloc::bad_alloc(char const *)" ([email protected]@@[email protected]@Z) 

He leído en el MSDN, estas advertencias pueden ser causados ​​por la declaración de __declspec (dllimport). Pero, en mis clases de mi lib, no he declarado cosas así. Por ejemplo, aquí está mi clase Excepción:

#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 

Puede alguien decirme por qué estas advertencias aparecen y cómo eliminarlos?

Respuesta

17

Es causado por __declspec(import)en los símbolos mencionados como "importados", es decir. en public: __thiscall std::exception::exception(char const * const &). Esto puede deberse a una falta de coincidencia entre la opción del compilador para la selección del tiempo de ejecución (/MT (tiempo de ejecución de múltiples subprocesos estáticos) v.s. /MD (tiempo de ejecución dinámico)) y las opciones del preprocesador (_DLL definen). En particular, esas advertencias aparecerían si compila con /MT (o /MTd en configuración de depuración), pero _DLL se definió de alguna manera.

Así que asegúrese de no estar definiendo _DLL cuando no compila con /MD.

También es importante compilar todas las bibliotecas para el mismo tiempo de ejecución que el ejecutable, por lo que compruebe que la selección del tiempo de ejecución coincida para todos los proyectos y que esté vinculando la versión apropiada de las bibliotecas de terceros.

+2

De hecho, esto se debe a que mi proyecto ejecutable se definió en "DLL de subprocesos múltiples \ MD" en lugar de "Varios subprocesos \ MT" ... No sé por qué. .. Así que gracias ;-) – Cedekasme

0

Esto no es relevante para el problema del OP, pero también he visto LNK4217 cuando se vincula en una biblioteca local a un archivo ejecutable, donde no existe una discrepancia en la biblioteca del tiempo de ejecución.

Algunas bibliotecas requieren una definición de preprocesador al compilarlas como estáticas (independientemente de si se utiliza el tiempo de ejecución estático o dinámico). Por ejemplo, libzmq (0MQ) requiere que se defina el símbolo ZMQ_STATIC al construir una biblioteca estática. De lo contrario, obtendrás LN2417 cuando vincules tu biblioteca a un ejecutable.

1

La falta de coincidencia de __declspec (dllexport)/__ declspec (dllimport) también puede ocurrir debido a las funciones/clases definidas en el encabezado; por ejemplo: Está construyendo una biblioteca compartida (.dll) que utiliza una combinación de funciones/clases definidas por encabezado/clases vinculadas/funciones (sin un archivo de interfaz específico estas necesitan usar __declspec (dllexport) mientras compila la lib compartida y __declspec (dllimport) mientras se usa). Un error común es definir __declspec (dllexport)/__ declspec (dllimport) para las partes que son realmente solo encabezado y por lo tanto no son parte de la lib compilada en sí.

0

Algunos info de Russ Keldorph en lo que hace realmente declspec (dllimport). (Sugiere usar el modificador /QSimplicit-import-)

Cuestiones relacionadas