+1  A: 

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.

Steven Richards
Good thinking but I already tried exactly that, and unfortunately it doesn't stop the link error. Bizarre...
demoncodemonkey
There definitely seems to be some funky behavior. Like you said, adding this block doesn't seem to fix it, but if I also add additional #defines (just random stuff) after that block in both xxx.cpp and xxx2.cpp, it seems to build correctly.
Steven Richards
No I can't get it to work. If you save both CPP files then yes it will fix it. But if you only save one of them after the DLL is insignificantly modified, then you'll get that error again. I will edit the question a little bit with the latest info.
demoncodemonkey
+3  A: 

This problem is caused by the new Managed Incremental Build feature in Visual Studio 2008. As you spotted, the metadata did change, but not in a way that the managed incremental build feature considers signifcant. However, if you force a recompile of one of the cpp files, it grabs the new metadata, embeds it in the obj, and then the linker sees a conflict.

There are two ways to resolve this problem. A simple way that seems to work, from demoncodemonkey's answer below is to specify an explicit version number in the referenced assembly metadata to instruct the compiler that the referenced assembly is in fact at the same version:

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.

The alternative way to avoid this problem is by disabling the feature. We may recompile some cpp files unnecessarily, but it's better than having the linker fail.

In the project properties, under Configuration Properties > General, set "Enable Managed Incremental Build" to No.

Nick Desjardins
This works for me as well. FYI I only had to disable it for the xxx project, not the shared project.
Steven Richards
Thanks, this worked for me. When an unsignificant change is made to Shared, the xxx project is rebuilt - which saves me from having to do it myself :o) I will submit this as a bug in VS2008.
demoncodemonkey
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=442615
demoncodemonkey
Thanks for logging the bug with Microsoft. This problem slows down my builds as well. Grr.
Nick Desjardins
See my other answer for the real accepted answer :)http://stackoverflow.com/questions/810827/lnk2022-metadata-operation-failed-driving-me-insane/1091175#1091175
demoncodemonkey
Included demoncodemonkey's answer in mine to give a more complete answer.
Nick Desjardins
+1  A: 

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 :(

demoncodemonkey