10

我正在将解决方案从 MSVS2005 移植到 MSVS2012。这些项目在 C++ .NET 中,但也使用自制的本地 C++ 库。我们使用 2005 构建项目没有问题,但现在,我无法使用 2012 构建项目。我收到以下错误消息:

MyFile.obj:错误 LNK2022:元数据操作失败 (801311E4):重复的托管类型具有不同的可见性。

这是什么意思?你需要什么信息来帮助我?

谢谢你的帮助?

4

5 回答 5

8

我发现了这个错误。它混合了这里建议的所有内容。

在项目的某个地方,包含了一个本地 C++ 头文件。此文件中的一个类通过以下方式公开:

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

但是在我自己的代码中,我包含了第二个标头,该标头本身包含定义了公开类的标头。因此,此时,该类在同一项目的一个文件中“公开”,而在另一个文件中“公开”。“具有不同可见性的重复”来自那里。

让我走上错误道路的唯一一点是错误消息:“重复的托管类型具有不同的可见性”。但在这里,它是一种非托管类型。

因此,如果有一天您遇到此错误,请在项目中查找#pragma make_public(...),然后在有问题的文件中查找重复的包含项。

于 2012-10-01T17:20:06.983 回答
4

我有同样的问题,并且确实有 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
于 2013-05-13T15:58:43.937 回答
3

Microsoft 在修补程序中修复了此问题:KB2848798

它帮助我将 VS2010 解决方案迁移到 VS2012。

你可以在这里下载

上述修补程序链接中的相关详细信息:CLR 问题 1

症状

从 Microsoft Visual Studio 2010 升级到 Visual Studio 2012 后,某些 C++/CLI 项目无法生成,并且它们报告类似于以下内容的链接器错误:

MSVCMRTD.lib(mstart.obj):错误 LNK2022:元数据操作失败 (801311E4)

于 2013-09-13T15:13:03.617 回答
1

我在尝试在 Win2008R2 机器上编译 VC++2013 项目时遇到了同样的问题(在 Win8.1 上编译得非常好)。只是删除任何重复的#include并不能解决我的问题。

然而,我随后启用了预编译头文件并将该项目的所有 make_public()语句移动到 stdafx.h,最终成功了!

于 2014-12-10T10:32:12.250 回答
1

从 VS2008 升级到 VS2012 有同样的问题。对我来说,修补程序的另一种解决方案是移动

#pragma make_public( ClassName )

从到目前为止的 .cpp 文件到 stdafx.h 的语句。

于 2013-09-29T15:42:34.977 回答