22

Visual StudioプロジェクトでCランタイムライブラリに静的にリンクするか動的にリンクするかについて、両側で議論を読みましたが、何を考えればよいのかまだ完全にはわかりません。

私のプロジェクトは、いくつかのサードパーティライブラリ(Python、HDF5、Trilinos、およびMicrosoft MPI)を取り込みます。これらのライブラリはそれぞれ、最終的な実行可能ファイルと同じランタイムライブラリでビルドする必要があります(そうでない場合、それらをリンクすることはできません)。静的にリンクする場合、これらの各ライブラリにはCランタイムのコピーが含まれます。最終的な実行可能ファイルにはランタイムの複数のコピーが含まれ、それらのいずれも相互に対話できないため、これにより問題が発生する可能性があることを読みました。しかし、同じシンボルが複数定義されている場合、リンカーは文句を言いませんか?

「DLLHell」は避けたいのですが、ランタイムの複数のコピーを静的にリンクすることで発生する可能性のある潜行性のエラーが心配です。私は物事を間違って読んでいますか?

また、Visual Studio 2005を使用していますが、ServicePack1ランタイムには下位互換性がないことを読みました。これは、SP1なしでビルドされたアプリは、同じ名前(msvcr80.dllなど)であっても、SP1 dllを持つマシンでは実行されないことを意味しますか?

4

4 に答える 4

27

静的にリンクすると、すべての EXE と DLL が膨張し、クラッシュが発生する可能性があります (たとえば、ある DLL のコードが、別の DLL の malloc() によって割り当てられたポインターを使用して free() を呼び出した場合)。

動的にリンクし、ランタイム DLL をプライベート アセンブリとして配置することで、両方の長所を活かすことができます。これは単に、ランタイム DLL とそのマニフェストを含む特別な名前のディレクトリのコピーを実行可能ファイルの隣に配置することを意味します。

詳細については、 http://msdn.microsoft.com/en-us/library/ms235291 (VS.80).aspx の「Visual C++ ライブラリ DLL をプライベート アセンブリとして展開する」セクションを参照してください。ただし、基本的にアプリケーションは次のようになります。

c:\Program Files\My App\MyApp.exe
c:\Program Files\My App\MyLibrary.dll
c:\Program Files\My App\Microsoft.VC80.CRT\Microsoft.VC80.CRT.manifest
c:\Program Files\My App\Microsoft.VC80.CRT\msvcr80.dll

最後の質問については、はい、ターゲット マシンが動作するには正しいバージョンのランタイム DLL が必要ですが、それらをプライベート アセンブリとして展開することで、それが保証されます。

もう 1 つの利点は、管理者以外のユーザーが (Program Files ではなく、別の場所に) アプリをインストールできることです。WinSxS 領域にファイルを書き込むためのアクセス許可は必要ありません。

于 2009-04-24T21:54:30.417 に答える
13

ランタイムの複数のコピーを取得するのは、ライブラリを DLL に静的にリンクする場合のみです。各 DLL がコピーを取得し、exe も同様です。それらがすべて静的ライブラリであり、DLL ではない場合、それらはすべて一緒にリンクされ、すべてのライブラリが同じランタイムを共有します。

それがリンカーの仕事です。

于 2009-04-24T22:21:50.507 に答える
1

静的ライブラリは、他の静的ライブラリに静的にリンクする必要はありません。メイン プロジェクトのすべての静的ライブラリをリンクするだけで済みます。そうすれば、コンパイラは複数のシンボルについて不平を言うことはありません。

于 2009-04-24T19:32:21.540 に答える
1

... 静的に実行してください... DLL を修正する試み 地獄はうまくいきませんでした... 静的リンケージを使用して、インストールに余分な 200k を追加するだけです。

于 2009-04-24T19:34:24.980 に答える