8

複数の DLL を使用する Windows アプリケーション (EXE) に取り組んでいます。開発は VCExpress 2005 (VC 8.0) で、C のみを使用しています。

LoadLibraryこれらの DLL の一部は、EXE によって読み取られる構成ファイルに従って 動的にロードされるプラグイン/アドオン/拡張機能です。

重要: アプリケーションは移植可能 (インストールせずに USB フラッシュ ドライブなどから実行できるという意味で) である必要があり、プラグイン DLL はアプリケーション EXE と同じフォルダーにない場合があります (従来の理由)。

MSVC6 では、これは簡単です。EXE と DLL をコンパイル、リンク、配布します。

MSVC8 では、C ランタイム ライブラリ (MSVCRT) が OS と共に配布されなくなったため、インストールされていることに依存することはできません。移植性の要件を満たすには、プライベート アセンブリを使用する必要があります。すべての EXE と DLL には、マニフェストが埋め込まれています。

私の問題:経由で読み込まれたプラグイン DLLLoadLibrary()は、EXE のフォルダーにあるプライベート アセンブリを見つけられないため、Microsoft.VC80.CRTアセンブリが winSxS にインストールされていない限り、それらを読み込もうとすると失敗します。

キャッチ: マニフェストがプラグイン DLL から削除されると、すべてが機能します。

私の質問:

  1. 問題のケースでは、Windows はアセンブリ検索シーケンスまたはダイナミック リンク ライブラリ検索順序のいずれにも従っていないようです。具体的には、アプリケーション (EXE) のロード元ではなく、DLL のロード元のパスでプライベート アセンブリを検索します。
    アセンブリを DLL に隣接させ、現在のディレクトリを変更して (作業ディレクトリのケースに関連するものを除外するために) これを確認し、期待どおりの動作を得ようとしました。LoadLibrarySxS で使用する場合、これが通常の動作であることを他の誰かが確認できますか?

  2. マニフェストがないと、DLLは、EXE のフォルダーでmsvcr80.dll(アセンブリ マニフェストではなく) 検出される非 SxS ロード順序にフォールバックすると想定するのは正しいですか?Microsoft.VC80.CRT.manifest

  3. (1) と (2) について私が正しければ、マニフェストを DLL から除外するだけで何を失うのでしょうか? 言い換えると、マニフェストを除外するだけで問題を解決できないのはなぜですか?

4

2 に答える 2

10

この問題を理解するには、アクティベーション コンテキストとは何かを理解する必要があります。

マニフェストを含む exe または dll には、アクティベーション コンテキストがあります。アクティベーション コンテキストは、マニフェストの解析時に検出されたウィンドウ クラス、依存アセンブリ、dll、および登録不要の com 参照のリストです。

マニフェストのない exe または dll は、プロセスの既定のアクティブ化コンテキストを使用します。これは通常、exe にアクティブ化コンテキストがある場合、exe のアクティブ化コンテキストです。

あなたの場合、dllには独自のアクティベーションコンテキストがあります-マニフェストがあるためです。そして、それは常に、アセンブリを検索するマニフェスト ファイル (を含むファイル/フォルダー) へのパスです。

これが、Windows が dll のフォルダーでプライベート アセンブリを検索することから始まる理由です。次に、それが失敗すると、Windows は、exe のルート フォルダーから始まる dll: の標準ロード ライブラリ検索パスを検索します。しかし、今はアセンブリではなく dll を検索しているため、dll を含むアセンブリ フォルダが見つかりません。

  1. いいえ。マニフェストがない場合、dll はデフォルトのアクティブ化コンテキスト (exe のマニフェスト) を使用するようにフォールバックします。このブログ記事で少し説明しています。

  2. マニフェストを除外します。失われるのは、dll に独自の依存アセンブリを指定させる機能です。したがって、dll が必要とする依存アセンブリをアプリケーション マニフェストに追加する必要があります。

于 2010-03-10T15:12:57.547 に答える
0

CRT と静的にリンクします。アプリケーション (純粋な C/C++) で .Net を使用しない限り、CRT と静的にリンクする可能性があります。

アプリケーションに .Net を導入したことで、静的にリンクされた CRT から動的にリンクされた CRT に移行せざるを得なくなりました。また、CRT DLL を明示的にインストールせずにローカルで参照する方法を見つけようとしましたが、見つかりませんでした。したがって、可能であれば、CRT と静的にリンクしてください。

于 2010-02-25T17:24:10.020 に答える