문제

VS2008 SP1을 사용하는 많은 프로젝트가있는 큰 솔루션이 있으며, 적어도 하루에 한 번은 LNK2022 오류에 직면합니다. 솔루션을 완전히 재건하면 잘 구축되지만 이것은 재미 있지 않습니다.

종속 DLL이 '무의미하게'변경 될 때 (즉, 방법이나 클래스를 변경하지 않고) 나중에 참조 프로젝트가 구축 될 때 발생합니다. 메타 데이터를 병합 할 때 실패합니다.

가장 먼저 주목해야 할 것은 공유 DLL이 #using 여러 .cpp 파일에서.
두 번째는 공유 DLL에서 AssemblyInfo.cpp를 삭제하면 문제가 사라진다는 것입니다. 이것이 현명한 수정인지 확실하지 않습니까?).

나는 가능한 한 다음으로 좁혔다 해결책 2 개의 CLR 클래스 라이브러리 프로젝트 (The 트리플 엑스 프로젝트는 공유):
alt text

각 파일의 내용은 다음과 같습니다.

shared.cpp :

public ref class Shared
{
};

인치:

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

xxx.cpp 및 xxx2.cpp :

#include "inc.h"

재생산하려면 먼저 솔루션을 재건하십시오. 괜찮을 것입니다.
이제 저장하십시오 shared.cpp 솔루션을 구축하면 잘 구축하고 표시됩니다.

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

이제 저장하십시오 xxx.cpp 솔루션을 구축하면 다음 메시지로 실패합니다.

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

편집하다:
xxx.obj와 xxx2.obj에 대한 IL의 차이는 다음과 같습니다.

(xxx.obj 용)
// AssemblyRef #2 (23000002)
// -------------------------------------------------------
// 토큰 : 0x23000002
// 공개 키 또는 토큰 :
// 이름 : 공유
// 버전 : 1.0.3412.16606
// 주요 버전 : 0x00000001
// 마이너 버전 : 0x00000000
// 빌드 번호 : 0x00000D54
// 개정 번호 : 0x000040
// 로케일 :
// 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와 충돌하고 있음을 의미합니다. 그렇다면 어떻게 해결할 수 있습니까?

도움이 되었습니까?

해결책 2

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

다른 팁

이 문제는 Visual Studio 2008의 새로운 관리 증분 빌드 기능으로 인해 발생합니다. 발견 한대로 메타 데이터는 변경되었지만 관리 된 증분 빌드 기능이 상당한 것으로 간주하는 방식은 아닙니다. 그러나 CPP 파일 중 하나를 다시 컴파일하면 새로운 메타 데이터를 잡고 OBJ에 포함시킨 다음 링커는 충돌을 본다.

이 문제를 해결하는 두 가지 방법이 있습니다. 작동하는 것처럼 보이는 간단한 방법 아래의 Demoncodemonkey의 답변 참조 된 어셈블리 메타 데이터에 명시 적 버전 번호를 지정하여 참조 된 어셈블리가 실제로 동일한 버전에 있음을 컴파일러에게 지시하는 것입니다.

바꾸다

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

~와 함께

[assembly:AssemblyVersionAttribute("1.0.0.1")];

안에 AssemblyInfo.cpp. 이렇게하면 버전이 증분 빌드간에 변경되지 않도록합니다.

이 문제를 피하는 대안적인 방법은 기능을 비활성화하는 것입니다. 일부 CPP 파일을 불필요하게 다시 컴파일 할 수 있지만 링커가 실패하는 것보다 낫습니다.

프로젝트 속성에서 구성 속성> 일반에서 "관리 된 증분 빌드 활성화"를 NO에 설정하십시오.

xxx.cpp 및 xxx2.cpp에서 사용해보십시오.

#ifndef _PROTECT_MY_HEADER
#define _PROTECT_MY_HEADER
#include  "inc.h"
#endif

#pragma once 이 경우 헤더를 보호하기에 충분하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top