「RuntimeLibrary」の不一致が検出されました


114

C:\ cryptoppにCrypto ++をダウンロードして解凍しました。Visual Studio Express 2012を使用してすべてのプロジェクトを(readmeの指示に従って)内部にビルドしましたが、すべてが正常にビルドされました。次に、他のフォルダにテストプロジェクトを作成し、依存関係としてcryptolibを追加しました。その後、すべてのヘッダーを簡単に含めることができるように、インクルードパスを追加しました。コンパイルしようとすると、未解決のシンボルに関するエラーが発生しました。

これを修正するために、C:\cryptopp\Win32\Output\Debug\cryptlib.lib追加の依存関係をリンクするように追加しました。今私はこのエラーを受け取ります:

Error   1   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(cryptlib.obj)    CryptoTest
Error   2   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(iterhash.obj)    CryptoTest
Error   3   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(sha.obj) CryptoTest
Error   4   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(pch.obj) CryptoTest
Error   5   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(misc.obj)    CryptoTest
Error   6   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(queue.obj)   CryptoTest
Error   7   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(algparam.obj)    CryptoTest
Error   8   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(filters.obj) CryptoTest
Error   9   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(fips140.obj) CryptoTest
Error   10  error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(cpu.obj) CryptoTest
Error   11  error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(mqueue.obj)  CryptoTest

私も得ます:

Error   12  error LNK2005: "public: __thiscall std::_Container_base12::_Container_base12(void)" (??0_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(cryptlib.obj)    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   13  error LNK2005: "public: __thiscall std::_Container_base12::~_Container_base12(void)" (??1_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(cryptlib.obj)   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   14  error LNK2005: "public: void __thiscall std::_Container_base12::_Orphan_all(void)" (?_Orphan_all@_Container_base12@std@@QAEXXZ) already defined in cryptlib.lib(cryptlib.obj)   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   15  error LNK2005: "public: __thiscall std::locale::id::id(unsigned int)" (??0id@locale@std@@QAE@I@Z) already defined in cryptlib.lib(iterhash.obj) C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Warning 16  warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\LINK  CryptoTest
Error   17  error LNK1169: one or more multiply defined symbols found   C:\Data\Work\C++ VS\CryptoTest\Debug\CryptoTest.exe 1   1   CryptoTest

コンパイルしようとしたコードはシンプルでした(別のサイトから入手しました)。

#include <iostream>
#include <string>
#include "sha.h"
#include "hex.h"
using namespace std;

string SHA256(string data) {
    byte const* pbData = (byte*) data.data();
    unsigned int nDataLen = data.size();
    byte abDigest[32];

    CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen);

    return string((char*)abDigest);
}

int main(void) {

    return 0;
}

これを修正する方法はありますか?本当に今必要なのはSHA-256だけです。私はWindows 7 64ビットを使用していて、今日VS C ++をダウンロードしたので、それが最新バージョンになるはずです。



1
プロジェクトのランタイムライブラリをマルチスレッドデバッグ(crypto ++で使用されていた設定)に設定すると、コンパイルされます。:) どうもありがとうございます。
モモンガ2013

あなたが走ったとき、問題はずっと以前に起こりましたVCUpgrade成功として報告されたVCUpgrade障害の症状が表示されます。
JWW

回答:


233

(これはすでにコメントで回答されていますが、実際の回答がないため、これを書いています。)

この問題は、新しいバージョンのVisual C ++で発生します(古いバージョンは通常、サイレントにプログラムをリンクし、実行時にクラッシュして書き込みます)。これは、プログラムにリンクしているライブラリ(またはソースの一部)プログラム内のファイル)がCRT(Cランタイムライブラリ)の異なるバージョンを使用しています。

このエラーを修正するには、自分Project Propertiesのライブラリ(および/または使用しているライブラリ)に移動しC/C++、次にCode Generationに移動して、の値を確認する必要がありますRuntime Library。これは、リンクしているすべてのファイルとライブラリでまったく同じでなければなりません。(ルールはDLLとリンクするために少し緩和されていますが、ここでは「理由」と詳細については説明しません。)

現在、この設定には4つのオプションがあります。

  1. マルチスレッドデバッグ
  2. マルチスレッドデバッグDLL
  3. マルチスレッドリリース
  4. マルチスレッドリリースDLL

特定の問題は、「マルチスレッドデバッグ」(つまり、静的マルチスレッドデバッグCRT)で構築されたライブラリを、「マルチスレッドデバッグDLL」設定(つまり、動的マルチスレッドデバッグCRT)を使用して構築されているプログラムにリンクすることから生じているようです。この設定は、ライブラリまたはプログラム内にあります。とりあえず、これをプログラムで変更することをお勧めします。

Visual Studioプロジェクトはデバッグビルドとリリースビルド(および32/64ビットビルド)に異なるプロジェクト設定のセットを使用するため、これらのプロジェクト構成すべてで設定が一致していることを確認してください。

(いくつかの)詳細については、これらを見ることができます(上のコメントからリンクされています):

  1. MSDNのリンカーツール警告LNK4098
  2. MSDNの/ MD、/ ML、/ MT、/ LD(ランタイムライブラリを使用)
  3. VC11 Betaでビルドエラー-Bugzilla @ MozillaでMTdライブラリとMDd exeを混在させると失敗する

更新:(これは、これだけ多くの注意を払う必要がある理由を尋ねるコメントへの応答です。)

一緒にリンクしている2つのコード自体が標準ライブラリにリンクして使用している場合、2つのコードがどのように相互作用してデータを渡すかについて十分注意が払われない限り、標準ライブラリは両方とも同じである必要があります。一般に、ほとんどすべての状況で、(デバッグ/リリース、スレッド、および明らかにVisual C ++のバージョン、特にイテレータデバッグなどに関して)標準ライブラリランタイムのまったく同じバージョンを使用すると言えます。

問題の最も重要な部分はこれです:関数呼び出しのどちらかの側のオブジェクトのサイズについて同じ考えを持っています

たとえば、上記の2つのコードがとAと呼ばれているとしBます。Aは標準ライブラリの1つのバージョンに対してコンパイルされ、Bは別のバージョンに対してコンパイルされます。Aのビューでは、標準関数がそれに返すランダムオブジェクト(メモリブロック、イテレータ、FILEオブジェクトなど)には、特定のサイズとレイアウトがあります(C /でのコンパイル時に構造のレイアウトが決定され、修正されることに注意してください) C ++。)いくつかの理由のいずれかにより、同じオブジェクトのサイズ/レイアウトに関するBの考え方は異なります(追加のデバッグ情報、時間の経過に伴うデータ構造の自然な進化などが原因である可能性があります)。

ここで、Aが標準ライブラリを呼び出してオブジェクトを取得し、そのオブジェクトをBに渡し、何らかの方法でBがそのオブジェクトに触れた場合、Bがそのオブジェクトをめちゃくちゃにする可能性があります(たとえば、間違ったフィールドを書き込むか、末尾を超えた場合)それの等)

発生する可能性があるのは、上記の問題だけではありません。標準ライブラリの内部グローバルオブジェクトまたは静的オブジェクトも問題を引き起こす可能性があります。また、問題のあいまいなクラスもあります。

libs(静的ランタイムライブラリ)の代わりにDLL(動的ランタイムライブラリ)を使用すると、いくつかすべての面でこれが奇妙になります。

この状況は、連携して動作する2つのコードで使用されるすべてのライブラリに当てはまりますが、標準ライブラリはほとんど(すべてではないにしても)のプログラムで使用されるため、衝突する可能性が高くなります。

私が説明したのは、ライブラリのバージョンを混在させた場合に明らかになる、実際の混乱の単純化された簡略版です。それがなぜあなたがそれをしてはいけないのかについての考えをあなたに与えることを願っています!


私は少し混乱しています。OPのエラーLNK2038です。それはすべてのLIBSに発生しませんので、私はそれは不可能CRTのフレーバーをミックスして作るいくつかのCRTの設定で暗号++フィドルを疑う-通常それは単なる警告(LNK4098)であり、あなたがあり、あなたが何をすべきかを知っていれば安全である(、推奨されませんただし、制限付きで可能です。例:stackoverflow.com/a/19944935/948581)。しかし、Crypto ++がこのように影響を受ける理由はわかりません。

1
@Tibo:これらはDLLのインポートライブラリではありません。Crypto ++は実際にはここのプログラムに静的にリンクされていると思います。これは、あるモジュールで別のモジュールとリンクされている標準ライブラリの不一致が(おそらく)「1つの定義ルール」に違反していることを意味します。それは悪いです。これはエラーではありませんでした。リンカー/ライブラリアンがモジュールに「タグ付け」を開始したVC10まで、リンカーはこれを検出することもできなかったため(関数/タイプ名は同じでしたが、本体と定義が大幅に異なりました)ビルドの構成に関する追加情報で生成されました...
yzt

@Tibo:...(前のコメントからの続き)たとえば、OPが報告しているエラーの最初のブロックを見てください。そこでは、「ランタイムライブラリは、」暗号++ライブラリとOPのプログラムのオブジェクトファイルの両方のタグであり、その値は「MDd_DynamicDebugそれらの一つと」用「MTd_StaticDebug他のために」。このように、2つのオブジェクトファイルをリンクしようとするリンカーは、オブジェクトファイルを生成したリンカーが関連情報、特にODRに違反する可能性のある設定でタグ付けした場合、まったく新しいクラスのエラーを検出して報告できます。
2015

私はあなたに全く同意しますが、ここにはまだ謎の領域があります。OPの問題については、彼はCrypto ++からの「dll.h」をインクルードしていると思います。その後、DLLのインポートライブラリの代わりに静的libに対してリンクしようとします。しかし、別のコンピューターではなく、あるコンピューターでまったく同じエラーが表示されました(VS2013の最終的なsp4->エラー、VS2013コミュニティsp5-> ok)...

1
@yzt解決策を見つけました。/ ZW swicthを使用する代わりに、WindowsはWRLと呼ばれるラッパーを使用してCOM経由でWinRT APIを使用する方法を提供します。/ ZWを使用しないと、COM実装の詳細が非表示になるため、コーディングが少し難しくなるだけですが、/ ZWなしでWinRTを使用することは可能です。
Sahil Singh

3

C:\ cryptoppにCrypto ++をダウンロードして解凍しました。Visual Studio Express 2012を使用してすべてのプロジェクトを(readmeの指示に従って)内部にビルドしましたが、すべてが正常にビルドされました。次に、他のフォルダにテストプロジェクトを作成し、依存関係としてcryptolibを追加しました。

変換はおそらく成功しませんでした。成功したのは、VCUpgradeの実行だけでした。実際の変換自体は失敗しましたが、表示されているエラーが発生するまでわかりません。詳細については、Crypto ++ wikiのVisual Studioを参照してください。


これを修正する方法はありますか?

問題を解決するには、vs2010.zip静的C / C ++ランタイムリンク(/MTまたは/MTdvs2010-dynamic.zipが必要な場合、または動的C / C ++ランタイムリンク(/MTまたは/MTd)が必要な場合は、ダウンロードする必要があります。どちらも、VCUpgradeによって生成される潜在的なサイレント障害を修正します。


vs2010.zipvs2010-dynamic.zipおよび最新のGitHubソースvs2005-dynamic.zipから構築されています。この記事の執筆時点(2016年6月1日)では、これは事実上Crypto ++ 5.6.4より前のバージョンです。5.6.2や5.6.3のような下位レベルのCrypto ++でZIPファイルを使用している場合、軽微な問題が発生します。

私が知っている2つの小さな問題があります。最初はの名前の変更であるbench.cppbench1.cpp。エラーは次のいずれかです。

  • C1083: Cannot open source file: 'bench1.cpp': No such file or directory
  • LNK2001: unresolved external symbol "void __cdecl OutputResultOperations(char const *,char const *,bool,unsigned long,double)" (?OutputResultOperations@@YAXPBD0_NKN@Z)

修正方法は、(1)cryptest.vcxprojメモ帳で開いてを見つけbench1.cpp、名前をに変更することbench.cppです。または(2)ファイルシステムでに名前bench.cppを変更しbench1.cppます。このファイルは削除しないでください。

2番目の問題は、移動するターゲットであるため少しトリッキーです。5.6.2や5.6.3などの下位レベルのリリースには、GitHubで利用可能な最新のクラスがありません。欠落しているクラスファイルには、HKDF(5.6.3)、RDRAND(5.6.3)、RDSEED(5.6.3)、ChaCha(5.6.4)、BLAKE2(5.6.4)、Poly1305(5.6.4)などが含まれます。

修正は、不足しているソースファイルを下位レベルのリリースには存在しないため、Visual Studioプロジェクトファイルから削除することです。

別のオプションは、最新のソースから欠落しているクラスファイルを追加することですが、複雑になる可能性があります。例えば、情報源の多くは微妙最新の依存config.hcpu.hそしてcpu.cpp。「繊細さ」は、パフォーマンスの低いクラスを取得していることに気付かないことです。

パフォーマンスの低いクラスの例はBLAKE2です。config.hコンパイル時のARM-32およびARM-64検出を追加します。コンパイル時の検出に依存するランタイムARM命令検出cpu.hcpu.cpp追加します。他のファイルなしでBLAKE2を追加すると、検出は行われず、直接のC / C ++実装が得られます。おそらく、バニラC / C ++のバイトあたり40サイクル程度に対して、バイトあたり9〜12サイクルで実行されるNEONの機会を逃していることに気付かないでしょう。


cryptopp wikiの指示に従い、vs2010-dynamic.zipをダウンロードして、その内容をcryptopp563コードに貼り付けました。いくつかのソースファイルをビルドして欠落させました。ウィキでは、zipはgithub上の最新のプロジェクト用であり、不足しているファイルを削除するだけであるとウィキは言っています。削除されました。プロジェクトはビルドされません:4つのリンクエラー、1つの例:エラーLNK2001:未解決の外部シンボル "void __cdecl OutputResultOperations(char const *、char const *、bool、unsigned long、double)"(?OutputResultOperations @@ YAXPBD0_NKN @ Z)
Yaniv 2016年

プロジェクトから欠落しているbench.cppがあることがわかりました。しかし、その後も、この修正をfiptest.cpp github.com/weidai11/cryptopp/pull/151/files?diff=splitに適用するまでコンパイルされませんでした。プロジェクトのzipファイルを追加するなど、これらにいくつかの順序を付けたいと思いますgitか何かに。そして、はい、コンパイラがVS2015 update 2であると言うことを怠っていました。結論として、私が書いたヒントに従ってください。
Yaniv 2016年

@Yaniv-最初のコメントについて、他のユーザーが問題を経験しないようにするために何をお勧めしますか?2番目のコメントについては、完全にテストされたら、パッチを取得する予定です。その間に私たちにできることはありますか?(私はこの回答に追加情報を追加しましたが、ユーザーが問題を起こさないようにしたいです)。
jww 2016年

まず、これを実行してくれてありがとう。Crypto ++は本当に素晴らしいです。ビルドの問題に関しては、ウィンドウslnとプロジェクトファイルをプロジェクト内の最新のファイルと互換性を保つようにしてください。もちろん、これらの変更により、これらのウィンドウビルドは何らかの形でコードベースにリンクされ、ソースツリー上にある可能性もあります。それが多すぎる場合は、少なくともVisual Studioビルド環境のzipファイルが現在の安定した公式リリースと互換性があることを確認してください。
Yaniv

fiptest.cppのパッチについて-それはVS2015とは何か違うようですので、VS2015を使用したい人は誰でもこのパッチを適用する必要があると思います。これは、VS2015の正しいデバッグコールバックを定義しているように見える#ifdefブロックのもう1つのケースであり、手動でパッチを適用するのは非常に簡単です。
Yaniv

3

ITERATOR_DEBUG_LEVELの不一致とともにこの問題が発生しました。結局日曜日の夜の問題は大丈夫でよかったように思えたので、私はしばらくの間出られました。VS2017 IDE(ソリューションエクスプローラー)での作業最近、別のプロジェクトから自分のプロジェクトへのソースファイル参照(ctrl-drag)を追加/コピーしました。プロパティ-> C / C ++ /プリプロセッサ- プロジェクトレベルではなくソースファイルレベルで調べたところ、リリース構成では、このソースファイルにNDEBUGではなく_DEBUGが指定されていることに気付きました。それが問題を取り除くために必要なすべての変更でした。


1

リンカーライブラリにmsvcrtd.libのCRTを追加することで問題を解決できます。cryptlib.libはCRTバージョンのデバッグを使用したためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.