LNK2022 (Duplicate managed types have different vi

2020-03-12 04:03发布

问题:

I'm porting a solution from MSVS2005 to MSVS2012. The projects are in C++ .NET but use homemade native C++ libraires too. We had no problem building the projects with 2005 but now, I'm unable to build a project using 2012. I get the following error message:

MyFile.obj : error LNK2022: metadata operation failed (801311E4) : Duplicate managed types have different visibilities.

What does this mean? What info do you need to help me?

Thanks for your help?

回答1:

I found the bug. It is a mix of everything that has been suggested here.

Somewhere in the project, a native C++ header file is included. A class in this file is made public with:

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

But in my own code, I include a second header that itself includes the header where the made public class is defined. So, at this point, the class is "made public" in one file and "not made public" in another file in the same project. The "duplicate with different visibilities" comes from there.

The only point that sent me on the wrong path was the error message: "Duplicate managed types have different visibilities". But here, it is an unmanaged type.

So, if you encounter this error someday, look for a #pragma make_public(...) in the project then look for a duplicated inclusion in your problematic file.



回答2:

I had the same problem, and indeed had the same condition described in dom_beau's answer, so I'm pretty sure I had the same underlying cause as well. However, to be able to resolve the error, I had to find the actual offending classes (there were a few, and the error messages do little to help you find them!).

So I wrote the following LINQ query which finds all classes defined in multiple *.obj files with conflicting visibilities. It may be useful to someone, so I'm posting it here.

// 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


回答3:

Microsoft fixed this issue in hotfix: KB2848798.

It helped me to migrate VS2010 solution to VS2012.

You can download it here

Relevant detail from above hotfix link: CLR issue 1

Symptoms

After you upgrade from Microsoft Visual Studio 2010 to Visual Studio 2012, some C++/CLI projects cannot build, and they report linker errors that resemble the following:

MSVCMRTD.lib(mstart.obj) : error LNK2022: metadata operation failed (801311E4)



回答4:

Had the same issue upgrading from VS2008 to VS2012. An alternative solution to the hotfix for me was to move the

#pragma make_public( ClassName )

statement from the .cpp file where it was up to now to stdafx.h.



回答5:

I had the same problem trying to compile a VC++2013 project on a Win2008R2 machine (which compiled absolutely fine on Win8.1). Just removing any duplicate #include did not solve the problem for me.

However, I then enabled precompiled headers and moved all make_public() statements of that project to stdafx.h, and that finally did it!