“LNK2022:元数据操作失败"让我发疯 [英] "LNK2022: metadata operation failed" driving me insane

查看:23
本文介绍了“LNK2022:元数据操作失败"让我发疯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含很多项目的大型解决方案,使用 VS2008 SP1,并且每天至少遇到一次 LNK2022 错误.如果我完全重建解决方案,它构建得很好,但这并不好玩.

当依赖的 DLL 被轻微"更改(即不更改任何方法或类)时会发生这种情况,并且稍后会构建引用项目.合并元数据时失败 - 不管这意味着什么.

首先要注意的是,共享 DLL 是通过多个 .CPP 文件中的 #using 引用的.
第二件事是,如果我从共享 DLL 中删除 AssemblyInfo.cpp,那么问题就会消失(但我是

这是每个文件的内容:

Shared.cpp:

公共参考类共享{};

inc.h:

#pragma once#使用Shared.dll"公共参考类 Common{私人的:共享^ m_fred;};

xxx.cpp 和 xxx2.cpp:

#include "inc.h"

要重现,首先重建解决方案.它会构建好的.
现在保存 Shared.cpp 并构建解决方案,它将构建良好并显示:

<代码>...2>------构建开始:项目:xxx,配置:调试Win32 ------2>检查 'd:xxxxxxDebugShared.dll' 更改...2> 在 'd:xxxxxxDebugShared.dll' 中未发现重大变化.2>xxx - 0 个错误,0 个警告========== 构建:2 成功,0 失败,0 最新,0 跳过 ==========

现在保存 xxx.cpp 并构建解决方案,它失败并显示以下消息:

1>------ 构建开始:项目:xxx,配置:调试 Win32 ------1>正在编译...1>xxx.cpp1>正在链接...1>xxx2.obj:错误 LNK2022:元数据操作失败(80131188):重复类型(类型:Common;字段:m_fred)中的字段声明不一致:(0x04000001).1>LINK : 致命错误 LNK1255: 链接因元数据错误而失败1>xxx - 2 个错误,0 个警告========== 构建:0 成功,1 失败,1 最新,0 跳过 ==========

编辑:
xxx.obj 和 xxx2.obj 的 IL 区别如下:

(对于 xxx.obj)
//AssemblyRef #2 (23000002)
//--------------------------------------------------------
//令牌:0x23000002
//公钥或令牌:
//名称:共享
//版本:1.0.3412.16606
//主要版本:0x00000001
//次要版本:0x00000000
//内部版本号:0x00000d54
//修订号:0x000040de
//语言环境:
//HashValue Blob: 1c bb 8f 13 7e ba 0a c7 26 c6 fc cb f9 ed 71 bf 5d ab b0 c0
//标志:[无] (00000000)

(对于 xxx2.obj)
//AssemblyRef #2 (23000002)
//--------------------------------------------------------
//令牌:0x23000002
//公钥或令牌:
//名称:共享
//版本:1.0.3412.16585
//主要版本:0x00000001
//次要版本:0x00000000
//内部版本号:0x00000d54
//修订号:0x000040c9
//语言环境:
//HashValue Blob: 64 af d3 12 9d e3 f6 2b 59 ac ff e5 3b 38 f8 fc 6d f4 d8 b5
//标志:[无] (00000000)

这对我来说意味着 xxx2.obj 仍在使用旧版本的 Shared.dll,这与使用更新的 Shared.dll 的 xxx.obj 冲突.那么我该如何解决呢?

解决方案

Microsoft 回复了我的 Connect 帖子,提供了更好的解决方法:

<块引用>

看起来问题是由之间的版本不匹配两个 .objs.更好的解决方法是替换

[程序集:AssemblyVersionAttribute("1.0.*")];

[程序集:AssemblyVersionAttribute("1.0.0.1")];

在 AssemblyInfo.cpp 中.这将确保版本不变在增量构建之间.

这对我有用,显然这比禁用该功能更可取.
无论如何,已选择接受的答案,现在无法更改:(

I have a big solution with lots of projects, using VS2008 SP1, and at least once a day I encounter the LNK2022 error. If I do a full rebuild of the solution it builds fine, but this is not fun.

It happens when a dependent DLL is changed 'insignificantly' (i.e. without changing any methods or classes), and the referencing project is later built. It fails when merging the metadata - whatever that means.

First thing to note is that the shared DLL is referenced with #using from multiple .CPP files.
Second thing is that if I delete the AssemblyInfo.cpp from the shared DLL then the problem goes away (but I'm not sure if this is a sensible fix?).

I've narrowed it down as far as possible into the following solution containing 2 CLR Class Library projects (the xxx project depends on Shared):

Here are the contents of each file:

Shared.cpp:

public ref class Shared
{
};

inc.h:

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

xxx.cpp and xxx2.cpp:

#include "inc.h"

To reproduce, first rebuild the solution. It will build OK.
Now save Shared.cpp and build the solution, it will build fine and show:

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

Now save xxx.cpp and build the solution, it fails with the following message:

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

EDIT:
The differences between the IL for xxx.obj and xxx2.obj are as follows:

(for xxx.obj)
// AssemblyRef #2 (23000002)
// -------------------------------------------------------
// Token: 0x23000002
// Public Key or Token:
// Name: Shared
// Version: 1.0.3412.16606
// Major Version: 0x00000001
// Minor Version: 0x00000000
// Build Number: 0x00000d54
// Revision Number: 0x000040de
// Locale:
// HashValue Blob: 1c bb 8f 13 7e ba 0a c7 26 c6 fc cb f9 ed 71 bf 5d ab b0 c0
// Flags: [none] (00000000)

(for xxx2.obj)
// AssemblyRef #2 (23000002)
// -------------------------------------------------------
// Token: 0x23000002
// Public Key or Token:
// Name: Shared
// Version: 1.0.3412.16585
// Major Version: 0x00000001
// Minor Version: 0x00000000
// Build Number: 0x00000d54
// Revision Number: 0x000040c9
// Locale:
// HashValue Blob: 64 af d3 12 9d e3 f6 2b 59 ac ff e5 3b 38 f8 fc 6d f4 d8 b5
// Flags: [none] (00000000)

This implies to me that xxx2.obj is still using the old version of Shared.dll, and that is conflicting with xxx.obj which is using the updated Shared.dll. So how can I workaround that then?

解决方案

Microsoft replied to my Connect post, with a much better workaround:

It looks like the problem is caused by the mismatch in version between the two .objs. A better workaround is to replace

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

with

[assembly:AssemblyVersionAttribute("1.0.0.1")];

in AssemblyInfo.cpp. This will ensure that the version does not change between incremental builds.

This works for me and obviously this is preferable to disabling the feature.
Anyway the accepted answer has been chosen and cannot be changed now :(

这篇关于“LNK2022:元数据操作失败"让我发疯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆