私が達成しようとしていることの長い物語
DLL をプラグインとして動的にロードするプログラムに取り組んでいます。Microsoft Visual C++ 2008 を使用してプログラムをコンパイルしています。それでも、Qt が動作するすべての Visual C++ バージョンをサポートする必要があると仮定しましょう。プログラム ディレクトリのレイアウトは次のとおりです。
| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| program.exe
program.exe
すべてのプラグイン DLL ファイルを検出し、それらに対して LoadLibrary() を実行し、特定の署名関数を呼び出して、それが実際にプラグインであるかどうかを調べます。これは、MSVC90 用の vcredist がインストールされているコンピューターでうまく機能します。当然のことながら、プログラムをすべてのコンピューターで動作させるには、msvc*.dll ファイルと適切なマニフェスト ファイルを使用してプログラムを再配布する必要があります。Qt DLL を実行するには redist も必要です。
ここで、選択した Visual Studio のバージョンに応じて、適切な redist DLL とマニフェストを自動的にコピーするように cmake をセットアップしました。簡単にするために、私は MSVC90 を使用していると仮定します。redist がプログラム ディレクトリにコピーされると、レイアウトは次のようになります。
| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| msvcm90.dll
| msvcp90.dll
| msvcr90.dll
| Microsoft.VC90.CRT.manifest (I'm also aware that this file is bugged in VS2008)
| program.exe
マニフェスト ファイルのバグについて: http://www.cmake.org/pipermail/cmake/2008-September/023822.html
問題
このレイアウトのプログラムは、redist がインストールされていないコンピューターで動作するようになりましたが、プラグインは読み込まれません。プラグインをロードするには、次のいずれかを実行する必要があります。
- マニフェスト ファイルを
plugins/
ディレクトリにコピーします。msvc*.dll ファイルへのすべての参照をマニフェスト ファイルから削除します。これは機能しますが、使用されている MSVC のバージョンに応じて、編集されたマニフェスト ファイルの異なるバージョンをサポートする必要があるため、うまくいきません。また、2008 以外の Visual Studio でこれが壊れないかどうかもわかりません。 - redist 全体を
plugins/
ディレクトリにコピーします。これにはマニフェスト ファイルを変更する必要はありませんがprogram.exe
、msvc*.dll ファイルをプラグインと見なして愚かにもロードしようとします。当然、これは正常に失敗するため、大きな害はありません。もう 1 つの欠点は、プログラム パッケージのサイズが 1 MB 以上大きくなることです。ただし、これらの問題はどちらも私が一緒に暮らすことができるものです。 - /MT スイッチを使用してプラグインをコンパイルします。
program.exe
簡単なテストでは、これが実際に機能することが示されていますが、Qt と/MDの両方が将来的に壊れないかどうかはわかりません。
質問)
最善の解決策は何ですか? 正しい解決策は何ですか?正しい解決策が複数ある場合、ベスト プラクティスはどれですか。これをやろうとしたのは私が初めてですか?
更新 1 (2012 年 11 月 18 日)
質問には答えられないままですが、私は最も頭痛の少ないルートを選ぶことにしました。今まで私は解決策 1 を使用してきましたが、それを使い続けることにしました。CMake は、ユーザーが 2008 以外のバージョンの MSVC を使用していることを検出すると、自動パッケージングが完全にはサポートされていないことを示す警告メッセージを表示します。