12

私は、DLL のロードの問題に対する洗練された解決策を考え出そうと頭を悩ませています。DLL をロードする他の lib ファイルに静的にリンクするアプリケーションがあります。私はDLLを直接ロードしていません。%working_folder%\dlls のようなもの - %working_folder% に数十個 (はい...数十個) の DLL を入れたくない.

検索パス@スタートアップを調整するメインアプリの一部である何かを開発しようとしています。私が直面している問題は、この新しいカスタム DLL パスがシステム検索パスにないことです。アプリを起動すると、必要な DLL が適切な場所にないため、アプリがクラッシュします (STATUS_DLL_NOT_FOUND)。私がやりたいことは、この新しいカスタム DLL フォルダーがプロセス環境変数の検索パスにあるかどうかを @ startup で確認し、そうでない場合は追加することです。問題は、アプリケーションが 1 行のコードを実行する前に、これらすべての DLL を読み込もうとすることです。

これを修正するにはどうすればよいですか? 最初に起動し、環境変数を適切に調整し、CreateProcess を介してメイン アプリを起動するヘルプ アプリを作成することを検討しました。これはうまくいくと確信していますが、開発者にとっては困難です。彼らがメイン アプリをデバッグするとき、最初にヘルパー アプリを起動するつもりはありません。

レジストリ アプリ パス機能を試しましたが、成功しませんでした。以前と同じ鶏と卵の問題。

ここで何ができますか?

4

3 に答える 3

2

[編集 - 質問を読み直した後、あなたが抱えている問題は、main開始前にDLLがロードされていることです]

これらのライブラリは C++ で記述されており、グローバル スコープ内のいくつかのオブジェクトのコンストラクターから DLL をロードしていると思います。これは問題です。Yossi Kreininの言葉を引用させてください。

main() で最初に実行します。C++ を使用する場合は、main() の前に最初に実行する必要があります。これは、グローバル変数のコンストラクターで FP を使用できるためです。これは、コンパイラ固有の翻訳単位の初期化順序を把握し、独自の C/C++ スタートアップ ライブラリをコンパイルし、LD_PRELOAD などを使用してコンパイル済みスタートアップ ライブラリのエントリ ポイントをオーバーライドし、静的にリンクされたプログラムでそれを上書きすることによって実現できます。 FP を使用する前に FloatingPointSingleton::instance() を呼び出すことを強制するコーディング規則があるか、または main() の前に何かをしたい人を撃ちます。それはトレードオフです。

[以下の元の回答]

DLL のロードに使用される検索アルゴリズムについては、このページを参照してください。を使用SetDllDirectory()して、ディレクトリを DLL 検索パスに追加できます。

GetEnvironmentVariable()また、 およびを使用してディレクトリを PATH 環境変数に追加できるはずですSetEnvironmentVariable()

もう 1 つのオプションは、現在の作業ディレクトリを DLL を含むフォルダに変更することSetCurrentDirectory()です。相対ファイル名を使用してファイルをロードする場合は、DLL をロードした後に作業ディレクトリを元に戻すようにしてください。

于 2008-11-29T03:33:45.973 に答える
2

私の推奨事項は、DLL に遅延ロード リンクを使用し、SetDllDirectory() を十分に早い段階で呼び出して、メソッド/関数が呼び出されたときにそれらを見つけることができるようにすることです。

于 2010-01-05T02:22:51.077 に答える