2012-09-28 7 views
9

Estoy portando una solución de MSVS2005 a MSVS2012. Los proyectos están en C++ .NET pero también usan librerías caseras nativas de C++. No tuvimos problemas para construir los proyectos con 2005, pero ahora no puedo construir un proyecto con 2012. Recibo el siguiente mensaje de error:LNK2022 (los tipos administrados duplicados tienen visibilidades diferentes) en MSVS 2012

MyFile.obj: error LNK2022: operación de metadatos fallida (801311E4): Duplicate managed los tipos tienen diferentes visibilidades.

¿Qué significa esto? ¿Qué información necesitas para ayudarme?

Gracias por su ayuda?

+0

Puede obtener tipos duplicados de #incluido un archivo .h con una declaración de clase de referencia en múltiples archivos .cpp. El enlazador se cae cuando no coinciden exactamente. Como público en uno pero interno en otro. –

+0

Disculpe Hans, no entiendo perfectamente. ¿Cómo un encabezado incluido en muchos archivos fuente podría declarar la clase de referencia de una manera diferente ya que es el ** mismo ** código? –

+0

No lo sé, no puedo ver su código desde aquí. Las macros siempre son una buena forma de causar una pérdida aleatoria. –

Respuesta

7

Encontré el error. Es una mezcla de todo lo que se ha sugerido aquí.

En algún lugar del proyecto, se incluye un archivo de encabezado C++ nativo. Una clase en este archivo se hace público con:

#include "File_Where_ClassName_Is_Defined.h" 
#pragma make_public(ClassName) 

Pero en mi propio código, incluyo una segunda cabecera que sí incluye la cabecera, donde se define la clase pública realizada. Entonces, en este punto, la clase se "hace pública" en un archivo y "no hecho público" en otro archivo en el mismo proyecto. El "duplicado con diferentes visibilidades" proviene de allí.

El único punto que me envió en el camino equivocado fue el mensaje de error: "Los tipos administrados duplicados tienen visibilidades diferentes". Pero aquí, es un tipo no administrado.

Entonces, si encuentra este error algún día, busque #pragma make_public (...) en el proyecto y luego busque una inclusión duplicada en su archivo problemático.

+0

¡Increíble! Primero leí esto pensando que era una posibilidad remota, pero tenía exactamente este problema. Estaba usando 'make_public' para convertir una clase no administrada en una clase administrada inaccesible (a código C#). Al mover el pragma al archivo de inclusión principal lo resolví por mí. Gracias por tropezar con este por delante de mi !!! –

3

Tuve el mismo problema, y ​​de hecho tenía la misma condición descrita en la respuesta de dom_beau, así que estoy bastante seguro de que también tuve la misma causa subyacente. Sin embargo, para poder resolver el error, tuve que encontrar las clases ofensivas reales (¡había algunas, y los mensajes de error hacen poco para ayudarlo a encontrarlas!).

Así que escribí la siguiente consulta LINQ que encuentra todas las clases definidas en múltiples archivos * .obj con visibilidades contradictorias. Puede ser útil para alguien, así que lo estoy publicando aquí.

// Analyze text files produced by ildasm when given *.obj files. 
// Use "for %1 in (*.obj) do ildasm /text %1 > %1-ildasm.txt" to produce the files. 

from file in Directory.GetFiles(@"your project's intermediate folder") 
where file.EndsWith("-ildasm.txt") 
let lines = File.ReadAllLines(file) 
from i in Enumerable.Range(0, lines.Count() - 1) 
where lines[i].Contains("TypDefName:") 
let type = lines[i].Substring(16,lines[i].IndexOf(" (")-17) 
let flags = lines[i+1] 
group new {file, flags} by type into g 
where g.Select(t=>t.flags).Distinct().Count() > 1 
select g 
+0

+1: Parecía mucho trabajo para alguien que no estaba acostumbrado a ildasm y LINQ, pero funciona muy bien, me encontré con este mismo escenario y la consulta apuntó a la clase ofensiva. Agregué el pragma make_public que faltaba y lo construí con éxito. –

+0

Esa solución funcionó perfectamente para mí. Para la consulta LINQ utilicé LINQPad. –

3

Microsoft corrigió este problema en la revisión: KB2848798.

Me ayudó a migrar la solución VS2010 a VS2012.

Puede descargarlo here

detalle relevante desde arriba el enlace de hotfix: tema CLR 1

síntomas

Después de actualizar desde Microsoft Visual Studio 2010 a Visual Studio 2012, algunos de C++/CLI los proyectos no pueden compilar e informan errores del vinculador que se parecen a los siguientes:

MSVCMRTD.lib (mstart.obj): error LNK2022: operación de metadatos fallida (801311E4))

+0

Parece estar de vuelta en VS2013 Actualización 2 RC –

1

Tenía el mismo problema de actualización de VS2008 a VS2012. Una solución alternativa a la revisión para mí era mover la declaración

#pragma make_public(ClassName) 

desde el archivo .cpp donde estaba hasta ahora a StdAfx.h.

1

Tuve el mismo problema al intentar compilar un proyecto de VC++ 2013 en una máquina Win2008R2 (que compiló absolutamente bien en Win8.1). Simplemente eliminando cualquier duplicado #include no resolvió el problema para mí.

Sin embargo, a continuación, Habilité encabezados precompilados y se trasladó todosmake_public() declaraciones de ese proyecto para StdAfx.h, y que finalmente lo hice!

+0

Funcionó para mí. Solución fácil –

Cuestiones relacionadas