2

これは私が盲目的に受け入れ、「あるがまま」として従ったものです。その背後にある「理由」をより深く理解しようとしています。

  • 静的ライブラリ LibA - いくつかの C ランタイム呼び出しを利用します
  • スタティック ライブラリ LibB - いくつかの C ランタイム コールを利用
  • 実行可能アプリ - LibA、LibB、および一部の C ランタイム呼び出しを利用

ここにかなり詳しく文書化されており、リンカーの特定の呼び出しに渡されたすべてのモジュールが同じランタイム ライブラリ コンパイラ オプションでコンパイルされている必要がある他の多くの場所があります。

ここここで説明されているように、アプリの最終リンク中にすべてのシンボル解決が実行される場合、なぜそうなるのでしょうか? LibA と LibB がビルド時に使用する特定のランタイム ライブラリを指定する必要があるのはなぜですか? 彼らが使用する C ランタイム呼び出しは、ランタイム アプリがそのリンクに指定するものに対して解決するべきではありませんか?

これは他の C 開発環境の問題ですか、それとも Visual Studio 固有の問題ですか?

4

1 に答える 1

0

Hans Passant がコメントで述べたように、DLL ランタイムと静的リンク ランタイムの間で変更する必要があるグローバル状態項目がいくつかあります。彼の例よりもさらに悪いのは、作成したランタイムに基づいて型のサイズが変化する場合です。ただし、さらにいくつかの理由があります。

デバッグとリリース:
デバッグ ランタイムは、動的に割り当てられたメモリを囲むガード バイトを配置します。これにより、メモリ割り当てと解放コードが追加のチェックを実行できるようになり、二重解放や割り当てられたバッファ外への書き込みなどのメモリの問題を見つけるのに役立ちます。リリース ランタイムは、最適化のために余分なチェックを使用しません。したがって、メモリが 1 つで割り当てられ、別のメモリで解放されると、予測できない結果が生じる可能性があります。

DLL と静的リンケージ:
Windows では、経験則として、割り当てたモジュールと同じモジュールでメモリを解放する必要があります。つまり、msvcrt.dll でメモリを割り当てた場合は、そこでも解放する必要があります。したがって、アプリケーションの一部が静的ランタイムにリンクし、一部がランタイム DLL にリンクしている場合、この規則に違反する可能性があります。これが発生すると、例外を含む予期しない結果が発生する可能性もあります。

マルチスレッドとシングルスレッド:
これら 2 つのランタイム タイプ間で競合が発生する可能性があることは明らかです。シングル スレッド バージョンはスレッド セーフではないため、スレッド セーフを期待するものと組み合わせると、後で興味深いデバッグを行うことができます。新しいリリースでは唯一のオプションがマルチスレッドであるため、この違いは主に古い MS コンパイラにのみ存在します。

この同様の質問も参照してください: Visual Studio 2002 以降の異なるバージョンから構築された C コードの静的ライブラリの混在

于 2012-05-12T01:24:22.153 に答える