1. ホーム
  2. c++

[解決済み] RuntimeLibrary'にミスマッチが検出されました。

2022-05-11 08:56:20

質問

Crypto++をダウンロードし、C:⇄cryptoppに解凍しました。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++ をダウンロードしたので、それは最新バージョンであるはずです。

どのように解決するのですか?

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

この問題は Visual C++ の新しいバージョンで発生します (古いバージョンでは通常、プログラムをサイレントリンクするだけで、実行時にクラッシュして燃えてしまいます)。つまり、プログラムとリンクしているライブラリの一部 (または、プログラム自体の内部のソース ファイルの一部) が が異なるバージョンの CRT (C RunTime ライブラリ) を使用していることを意味します。

このエラーを修正するためには、あなたの Project Properties (および/または、使用しているライブラリのもの) に移動し、次に C/C++ そして Code Generation の値をチェックし Runtime Library の値をチェックします。 すべて で全く同じでなければなりません。(DLL とリンクする場合のルールはもう少し緩やかですが、ここでは "なぜ" と詳細を説明するつもりはありません)。

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

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

この特定の問題は、"Multithreaded Debug" (つまり、静的なマルチスレッド デバッグ CRT) でビルドされたライブラリを、"Multithreaded Debug" を使用してビルドされているプログラムに対してリンクしたことから発生しているように見えます。 DLL この設定は、ライブラリまたはプログラムのどちらかで変更する必要があります。今のところ、プログラムで変更することをお勧めします。

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

(いくつかの) 詳細情報については、以下を参照してください (上記のコメントからリンクされています)。

  1. リンカー ツールの警告 LNK4098 MSDNにて
  2. /MD, /ML, /MT, /LD (ランタイムライブラリ使用) MSDN 上
  3. VC11 Beta でのビルド エラー - MTd ライブラリと MDd exes の混合はリンクに失敗します。 Bugzilla@Mozilla にあります。

アップデイト : (ここまで配慮しなければならない理由を教えてほしいというコメントへの対応です)。

もし私たちが一緒にリンクしている2つのコードの断片が、それ自体標準ライブラリに対してリンクし、使用しているのであれば、標準ライブラリは、以下の場合を除き、それら両方に対して同じでなければなりません。 素晴らしい

を使用する場合、2 つのコード片がどのように相互作用し、データを受け渡しするかについて注意が必要です。一般的に、ほとんどすべての状況において、標準ライブラリ ランタイムのまったく同じバージョン (デバッグ/リリース、スレッド、および明らかに Visual C++ のバージョン、イテレーター デバッグなどの他のもののうち) を使用するようにと私は言うでしょう。

この問題の最も重要な部分は、これです。 関数呼び出しの両側でオブジェクトのサイズについて同じ考えを持つこと。 .

例えば、上記の2つのコードが AB . Aは コンパイルされた A はある標準ライブラリのバージョンに対して、B は別のバージョンに対してコンパイルされています。A から見ると、標準関数が返すランダムなオブジェクト (例えば、メモリブロック、イテレータ、または FILE オブジェクトなど) が特定のサイズとレイアウトを持っていると考えます (C/C++では構造体のレイアウトはコンパイル時に決定され固定されていることを思い出してください)。いくつかの理由のいずれかにより、同じオブジェクトのサイズ/レイアウトに関する B の考え方は異なります (追加のデバッグ情報、時間の経過によるデータ構造の自然な進化などが考えられます)。

さて、Aが標準ライブラリを呼び出してオブジェクトを取得し、そのオブジェクトを B に渡し、B が何らかの方法でそのオブジェクトに触れると、B がそのオブジェクトを台無しにする可能性があります (たとえば、間違ったフィールドを書く、または終わりを過ぎてしまう、など)。

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

DLL (静的ランタイムライブラリ) の代わりに DLL (動的ランタイムライブラリ) を使用する場合、これらすべてはいくつかの側面でより奇妙なものになります。

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

私が説明したことは、ライブラリのバージョンを混ぜた場合に待ち受けている実際の混乱の、明らかに水増しされ単純化されたバージョンです。なぜそれをやってはいけないのか、その理由を理解していただければ幸いです。