'"LNK2022: metadata operation failed" driving me insane
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:\xxx\xxx\Debug\Shared.dll' changes ...
2>No significant changes found in 'd:\xxx\xxx\Debug\Shared.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?
Solution 1:[1]
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 :(
Edit: I managed to unaccept my answer and mark Nick's answer as the accepted answer :)
Solution 2:[2]
Try this in xxx.cpp and xxx2.cpp:
#ifndef _PROTECT_MY_HEADER
#define _PROTECT_MY_HEADER
#include "inc.h"
#endif
#pragma once isn't enough to protect the header in this case.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Steven Richards |
