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

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

问题描述

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

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

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

这里是每个文件的内容:

共享.cpp:

public ref class Shared{};

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 : error LNK2022: metadata operation failed (80131188) : 重复类型中的字段声明不一致(类型:Common;字段:m_fred):(0x04000001).1>LINK : 致命错误 LNK1255: 由于元数据错误,链接失败1>xxx - 2 个错误,0 个警告========== 构建:0 成功,1 失败,1 最新,0 跳过 ==========

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

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

(对于xxx2.obj)
//装配参考 #2 (23000002)
//-------------------------------------------------------
//令牌:0x23000002
//公钥或令牌:
//名称:共享
//版本:1.0.3412.16585
//主要版本:0x00000001
//次要版本:0x00000000
//内部版本号:0x00000d54
//修订号:0x000040c9
//语言环境:
//哈希值 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 帖子,并提供了更好的解决方法:

<块引用>

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

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

[assembly: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天全站免登陆