我正在将解决方案从MSVS2005移植到MSVS2012。这些项目采用 C++ .NET 格式,但也使用自制的本机C++库。我们在 2005 年构建项目没有问题,但现在,我无法使用 2012 构建项目。我收到以下错误消息:
MyFile.obj :错误 LNK2022:元数据操作失败 (801311E4):重复的托管类型具有不同的可见性。
这是什么意思?您需要哪些信息来帮助我?
谢谢你的帮助?
我发现了这个错误。它是这里建议的所有内容的混合体。
在项目中的某个位置,包含一个本机C++头文件。此文件中的类是公开的:
#include "File_Where_ClassName_Is_Defined.h"
#pragma make_public( ClassName )
但是在我自己的代码中,我包含第二个标头,该标头本身包含定义公共类的标头。因此,此时,该类在一个文件中"公开",在同一项目的另一个文件中"不公开"。"具有不同可见性的副本"来自那里。
唯一让我走上错误路径的一点是错误消息:"重复的托管类型具有不同的可见性"。但在这里,它是一种非托管类型。
因此,如果有一天遇到此错误,请在项目中查找 #pragma make_public(...),然后在有问题的文件中查找重复的包含。
我遇到了同样的问题,并且确实遇到了dom_beau答案中描述的相同情况,所以我很确定我也有相同的根本原因。但是,为了能够解决错误,我必须找到实际有问题的类(有一些,错误消息对帮助您找到它们几乎没有帮助!
因此,我编写了以下 LINQ 查询,该查询查找多个 *.obj 文件中定义的所有类,这些类具有冲突的可见性。它可能对某人有用,所以我在这里发布它。
// 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
>Microsoft修补程序中修复了此问题:KB2848798。
它帮助我将VS2010解决方案迁移到VS2012。
您可以在此处下载
上述修补程序链接中的相关详细信息:CLR 问题 1
症状
从 Microsoft Visual Studio 2010 升级到 Visual Studio 2012 后,某些 C++/CLI 项目无法生成,并且它们报告类似于以下内容的链接器错误:
MSVCMRTD.lib(mstart.obj) : 错误 LNK2022: 元数据操作失败 (801311E4)
从VS2008升级到VS2012时遇到同样的问题。对我来说,此修补程序的另一种解决方案是移动
#pragma make_public( ClassName )
从 .cpp 文件到现在到 stdafx.h 的声明。
我在尝试在Win2013R2机器上编译VC ++ 2008项目时遇到了同样的问题(在Win8.1上编译绝对正常)。只是删除任何重复的 #include 并不能为我解决问题。
但是,我随后启用了预编译标头并将该项目的所有make_public()
语句移动到 stdafx.h,这终于做到了!