2012-04-04 5 views
2

これは私が盲目的に受け入れて、「それは方法」として続いています。私はそれの背後にある "なぜ"をより深く理解しようとしています。Visual Studio C-ランタイムライブラリのリンク動作の深い理解を求める

  • 静的ライブラリLIBA - は、いくつかのCランタイムは
  • 静的ライブラリLibBを呼び出しutulizes - いくつかのCランタイムが実行可能なアプリケーション
  • を呼び出して利用 - LIBA、LibBを利用し、いくつかのCランタイムがそれ

を呼び出しますhereと、リンカの呼び出しに渡されたすべてのモジュールが同じランタイムライブラリコンパイラオプションでコンパイルされていなければならない場所がたくさんあります。

herehereを議論したように、すべてのシンボルの解像度がAppの最後のリンクの間に実行されている場合は、なぜこれがそうですか? LibAとLibBは、ビルド時に使用する特定のランタイムライブラリを指定する必要があるのはなぜですか? Cランタイムコールは、ランタイムAppがそのリンクに指定したものに対してただ解決するべきではありませんか?

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

+2

CRTはちょうどそれがグローバルな状態をたくさん持っている、モジュールの概念と非常に互換性がありません。 errnoのような変数は良い例です。 EXEとDLLの間でその状態を共有できるようにするには、errnoの定義をハックして関数呼び出しにする必要があります。したがって、1つの共有値しか得られません。/MDによってトリガーされます。 errnoを参照する.objを_errno()を参照する別のものにリンクしようとすると動作しません。完全に正確ではなく、問題の代表的ではありません。 –

答えて

0

Hans Passant氏のコメントによれば、DLLランタイムと静的リンクランタイムの間で変更する必要があるグローバル状態項目がいくつかあります。彼の例よりも悪いのは、型のサイズが、それがランタイムを作成したものに基づいて変化するときです。リリース対

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

DLL:Windowsの中
、親指のルールは、あなたがそれを割り当てられた同じモジュールでメモリを解放しなければならないということです。言い換えると、msvcrt.dllにメモリを割り当てた場合は、そのメモリを解放する必要があります。したがって、アプリケーションの一部が静的ランタイムにリンクし、ランタイムDLLにリンクしている場合、このルールに違反する可能性があります。これが起こると、例外を含む予期しない結果を得ることもできます。 Singlethread対

マルチスレッド:
これら2つのランタイム型の間の競合の可能性が明らかです。シングルスレッドバージョンはスレッドセーフではないので、スレッド安全性が必要なものと混合すると、あとから面白いデバッグが可能になります。この区別は、新しいリリースではマルチスレッド化されている唯一のオプションなので、旧式のMSコンパイラでは主に存在します。

も参照してください、この同様の質問:Mixing Static Libraries of C Code built from different versions of Visual Studio 2002 and later

関連する問題