28

VS2008 SP1 を使用して、多くのプロジェクトで大きなソリューションを持っていますが、少なくとも 1 日に 1 回は LNK2022 エラーが発生します。ソリューションを完全に再構築すると問題なくビルドできますが、これは面白くありません。

これは、依存する DLL が「わずかに」(つまり、メソッドやクラスを変更せずに) 変更され、参照元のプロジェクトが後でビルドされた場合に発生します。メタデータをマージするときに失敗します-それが何を意味するにせよ。

最初に注意すべきことは、共有 DLL が#using複数の .CPP ファイルから参照されていることです。
2 つ目は、AssemblyInfo.cpp を共有 DLL から削除すると、問題が解決することです (ただし、これが賢明な修正であるかどうかはわかりません)。

2 つの CLR クラス ライブラリ プロジェクトを含む次のソリューションに可能な限り絞り込みました( xxxプロジェクトは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.16 606
// メジャー バージョン.
_
_
_ _
_
_ _
// フラグ: [なし] (00000000)

(xxx2.obj の場合)
// AssemblyRef #2 (23000002)
// ---------------------------------- ---------------------
// トークン: 0x23000002
// 公開鍵またはトークン:
// 名前: 共有
// バージョン: 1.0.3412.16 585
// メジャー バージョン.
_
_
_ _
_
_ _
// フラグ: [なし] (00000000)

これは、xxx2.obj がまだ古いバージョンの Shared.dll を使用しており、更新された Shared.dll を使用している xxx.obj と競合していることを意味します。では、どうすればそれを回避できますか?

4

3 に答える 3

12

Microsoftは私のConnectの投稿に返信しましたが、回避策ははるかに優れています。

この問題は、2つの.obj間のバージョンの不一致が原因であるようです。より良い回避策は、置き換えることです

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

[アセンブリ:AssemblyVersionAttribute( "1.0.0.1")];

AssemblyInfo.cpp内。これにより、インクリメンタルビルド間でバージョンが変更されないようになります。

これは私にとってはうまくいき、明らかにこれは機能を無効にするよりも望ましいです。
とにかく受け入れられた答えが選択され、今は変更できません:(
編集:私はなんとか私の答えを受け入れず、ニックの答えを受け入れられた答えとしてマークしました:)

于 2009-07-07T09:07:29.470 に答える
1

xxx.cpp と xxx2.cpp でこれを試してください:

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

#pragma onceこの場合、ヘッダーを保護するには不十分です。

于 2009-05-01T10:07:53.117 に答える