vscode visual studio spell golang color code beautiful visual-studio-2008 linker c++-cli metadata assemblyinfo

visual studio 2008 - visual - "LNK2022: error en la operación de metadatos" me está volviendo loco



vscode beautiful (3)

Este problema se debe a la nueva característica de creación incremental administrada en Visual Studio 2008. Según lo descubrió, los metadatos cambiaron, pero no de una manera que la característica de creación incremental administrada considere significativa. Sin embargo, si fuerza una recompilación de uno de los archivos cpp, este captura los nuevos metadatos, los incrusta en el objeto, y luego el enlazador ve un conflicto.

Hay dos formas de resolver este problema. Una forma simple que parece funcionar, a partir de la respuesta de demoncodemonkey a continuación, es especificar un número de versión explícito en los metadatos del ensamblaje al que se hace referencia para indicar al compilador que el ensamblado al que se hace referencia está de hecho en la misma versión:

Reemplazar

[assembly:AssemblyVersionAttribute("1.0.*")];

con

[assembly:AssemblyVersionAttribute("1.0.0.1")];

en AssemblyInfo.cpp. Esto asegurará que la versión no cambie entre las compilaciones incrementales.

La forma alternativa de evitar este problema es deshabilitando la función. Podemos recompilar algunos archivos cpp innecesariamente, pero es mejor que hacer que el enlazador falle.

En las propiedades del proyecto, en Propiedades de configuración> General, establezca "Habilitar la construcción incremental administrada" en No.

Tengo una gran solución con muchos proyectos, utilizando VS2008 SP1, y al menos una vez al día encuentro el error LNK2022. Si hago una reconstrucción completa de la solución, se construye bien, pero esto no es divertido.

Ocurre cuando un DLL dependiente se cambia ''de manera insignificante'' (es decir, sin cambiar ningún método o clase), y el proyecto de referencia se construye más tarde. Falla al fusionar los metadatos, sea lo que sea que eso signifique.

Lo primero que se debe tener en cuenta es que se hace referencia a la DLL compartida con #using de varios archivos .CPP.
Lo segundo es que si elimino AssemblyInfo.cpp de la DLL compartida, el problema desaparece (pero no estoy seguro de que sea una solución razonable ).

Lo he reducido lo más posible en la siguiente solution contiene 2 proyectos CLR Class Library (el proyecto xxx depende de Shared ):
texto alt http://i42.tinypic.com/jg2vds.png

Aquí están los contenidos de cada archivo:

Shared.cpp:

public ref class Shared { };

pulgada:

#pragma once #using "Shared.dll" public ref class Common { private: Shared^ m_fred; };

xxx.cpp y xxx2.cpp:

#include "inc.h"

Para reproducir, primero reconstruir la solución. Se construirá bien.
Ahora guarde Shared.cpp y compile la solución, se construirá bien y mostrará:

... 2>------ Build started: Project: xxx, Configuration: Debug Win32 ------ 2>Inspecting ''d:/xxx/xxx/Debug/Shared.dll'' changes ... 2>No significant changes found in ''d:/xxx/xxx/Debug/Shared.dll''. 2>xxx - 0 error(s), 0 warning(s) ========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Ahora guarde xxx.cpp y compile la solución, falla con el siguiente mensaje:

1>------ Build started: Project: xxx, Configuration: Debug Win32 ------ 1>Compiling... 1>xxx.cpp 1>Linking... 1>xxx2.obj : error LNK2022: metadata operation failed (80131188) : Inconsistent field declarations in duplicated types (types: Common; fields: m_fred): (0x04000001). 1>LINK : fatal error LNK1255: link failed because of metadata errors 1>xxx - 2 error(s), 0 warning(s) ========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

EDITAR :
Las diferencias entre la IL para xxx.obj y xxx2.obj son las siguientes:

(para xxx.obj)
// AssemblyRef # 2 (23000002)
// ------------------------------------------------ -------
// Token: 0x23000002
// Clave pública o Token:
// Nombre: Compartido
// Versión: 1.0.3412.16 606
// Versión mayor: 0x00000001
// Versión menor: 0x00000000
// Número de compilación: 0x00000d54
// Número de Revisión: 0x000040 de
// Localidad:
// HashValue Blob: 1c bb 8f 13 7e ba 0a c7 26 c6 fc cb f9 ed 71 bf 5d ab b0 c0
// Banderas: [ninguna] (00000000)

(para xxx2.obj)
// AssemblyRef # 2 (23000002)
// ------------------------------------------------ -------
// Token: 0x23000002
// Clave pública o Token:
// Nombre: Compartido
// Versión: 1.0.3412.16 585
// Versión mayor: 0x00000001
// Versión menor: 0x00000000
// Número de compilación: 0x00000d54
// Número de Revisión: 0x000040 c9
// Localidad:
// HashValue Blob: 64 af d3 12 9d e3 f6 2b 59 ac ff e5 3b 38 f8 fc 6d f4 d8 b5
// Banderas: [ninguna] (00000000)

Esto me implica que xxx2.obj sigue usando la versión anterior de Shared.dll, y eso está en conflicto con xxx.obj que usa la versión actualizada de Shared.dll. Entonces, ¿cómo puedo solucionar eso entonces?


Microsoft respondió a mi publicación de Connect, con una solución mucho mejor:

Parece que el problema se debe a la falta de coincidencia en la versión entre los dos .objs. Una mejor solución es reemplazar

[assembly: AssemblyVersionAttribute ("1.0. *")];

con

[assembly: AssemblyVersionAttribute ("1.0.0.1")];

en AssemblyInfo.cpp. Esto asegurará que la versión no cambie entre las compilaciones incrementales.

Esto funciona para mí y, obviamente, es preferible deshabilitar la función.
De todos modos, la respuesta aceptada ha sido elegida y no se puede cambiar ahora :(


Prueba esto en xxx.cpp y xxx2.cpp:

#ifndef _PROTECT_MY_HEADER #define _PROTECT_MY_HEADER #include "inc.h" #endif

#pragma once no es suficiente para proteger el encabezado en este caso.