Error de las herramientas del vinculador LNK2005

symbol ya definido en objeto

El símbolo symbol se definió más de una vez.

Este error precede al error irrecuperable LNK1169.

Posibles causas y soluciones

Por lo general, este error significa que se ha interrumpido la regla de definición única, que solo permite una definición para cualquier plantilla, función, tipo o objeto usado en un archivo de objeto determinado y solo una definición en todo el ejecutable para funciones u objetos visibles externamente.

Estas son algunas de las causas comunes de este error.

  • Este error se puede producir cuando un archivo de encabezado define una variable. Por ejemplo, si incluye este archivo de encabezado en más de un archivo de origen en el proyecto, se produce un error:

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Entre las posibles soluciones se incluyen:

    • Declare la variable extern en el archivo de encabezado: extern int global_int; y, luego, defínala y, opcionalmente, inicialícela en solo un archivo de origen: int global_int = 17;. Esta variable ahora es global y se puede usar en cualquier archivo de origen si la declara extern, por ejemplo, al incluir el archivo de encabezado. Se recomienda esta solución para variables que deben ser globales, pero un buen procedimiento de ingeniería de software minimiza las variables globales.

    • Declare la variable static: static int static_int = 17;. De este modo, se restringe el ámbito de la definición al archivo de objeto actual y se permite que varios archivos de objeto tengan su propia copia de la variable. No se recomienda definir variables estáticas en archivos de encabezado debido a la posibilidad de confusión con variables globales. Prefiere mover las definiciones de variables estáticas a los archivos de origen que las usan.

    • Declare la variable selectany: __declspec(selectany) int global_int = 17;. De esta manera, se indica al enlazador que seleccione una definición para que la utilicen todas las referencias externas y que descarte el resto. Esta solución a veces resulta útil al combinar bibliotecas de importación. Por lo contrario, no se recomienda como una manera de evitar errores del enlazador.

  • Este error se puede producir cuando un archivo de encabezado define una función distinta de inline. Si incluye este archivo de encabezado en más de un archivo de origen, obtendrá varias definiciones de la función en el ejecutable.

    // LNK2005_func.h
    int sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Entre las posibles soluciones se incluyen:

    • Agregue la palabra clave inline a la función:

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • Quite el cuerpo de la función del archivo de encabezado y deje solo la declaración; luego, implemente la función en solo un archivo de origen:

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • Este error también se puede producir si define funciones miembro fuera de la declaración de clase en un archivo de encabezado:

    // LNK2005_member_outside.h
    class Sample {
    public:
        int sample_function(int);
    };
    int Sample::sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Para corregir este problema, lleve las definiciones de función miembro dentro de la clase. Las funciones miembro definidas dentro de una declaración de clase se insertan implícitamente.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • Este error se puede producir si vincula más de una versión de la biblioteca estándar o CRT. Por ejemplo, si intenta vincular las bibliotecas de CRT comerciales y de depuración, o bien las versiones estáticas y dinámicas de una biblioteca, o dos versiones diferentes de una biblioteca estándar al ejecutable, este error puede notificarse muchas veces. Para corregir este problema, quite todas las copias de cada biblioteca del comando link, salvo una. No se recomienda combinar las bibliotecas comerciales y de depuración, ni versiones diferentes de una biblioteca, en el mismo ejecutable.

    Para indicarle al enlazador que use bibliotecas distintas de las predeterminadas, en la línea de comandos, especifique las bibliotecas que se van a usar y use la opción /NODEFAULTLIB para deshabilitar las bibliotecas predeterminadas. En el IDE, agregue referencias al proyecto para especificar las bibliotecas que se van a usar y, a continuación, abra el diálogo Páginas de propiedades del proyecto y, en la página de propiedades Enlazador, Entrada, establezca la propiedad Omitir todas las bibliotecas predeterminadas o la propiedad Omitir bibliotecas predeterminadas específicas para deshabilitar las bibliotecas predeterminadas.

  • Este error se puede producir si se combina el uso de bibliotecas estáticas y dinámicas cuando se usa la opción /clr. Por ejemplo, este error se puede producir si compila un archivo DLL para usarlo en el archivo ejecutable que se vincula en el CRT estático. Para corregir este problema, use solo bibliotecas estáticas o solo bibliotecas dinámicas para todo el ejecutable y para las bibliotecas que compile para usarlas en el ejecutable.

  • Este error se puede producir si el símbolo es una función empaquetada (creada al compilar con /Gy) y se incluyó en varios archivos, pero se cambió de una compilación a otra. Para corregir este problema, vuelva a compilar todos los archivos que incluyen la función empaquetada.

  • Este error se puede producir si el símbolo está definido de manera distinta en dos objetos miembros de diferentes bibliotecas, y se utilizaron los dos objetos miembros. Una manera de corregir este problema cuando las bibliotecas están vinculadas de manera estática es usar el objeto miembro de una sola biblioteca e incluir esa biblioteca primero en la línea de comandos del enlazador. Para usar ambos símbolos, debe crear una manera de distinguirlos. Por ejemplo, si puede compilar las bibliotecas desde el origen, puede encapsular cada biblioteca en un espacio de nombres único. Como alternativa, puede crear una biblioteca contenedora que use nombres únicos para encapsular las referencias a una de las bibliotecas originales, vincular la biblioteca nueva a la biblioteca original y, luego, vincular el archivo ejecutable a la biblioteca nueva en lugar de a la biblioteca original.

  • Este error se puede producir si se define dos veces una variable extern const y tiene un valor distinto en cada definición. Para corregir este problema, defina la constante solo una vez o use espacios de nombres o definiciones enum class para distinguir las constantes.

  • Este error se puede producir si usa uuid.lib combinado con otros archivos .lib que definen GUID (por ejemplo, oledb.lib y adsiid.lib). Por ejemplo:

    oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject
    already defined in uuid.lib(go7.obj)
    

    Para corregir este problema, agregue /FORCE:MULTIPLE a las opciones de la línea de comandos del enlazador y compruebe que uuid.lib es la primera biblioteca a la que se hace referencia.