4

Windows では、次のファイル編成を検討してください。

[app folder]
    app.exe
    [folder 'sub']
        com_server.dll
        regular.dll
        helper.dll

また、次のことを前提とします。

  • com_server.dll と regular.dll は両方とも、helper.dll 内の関数に静的にリンクされているため、helper.dll はそのときに読み込まれます。
  • app.exe には静的な依存関係はありません。
  • com_server.dll COM オブジェクトが Windows に登録されている
  • フォルダ 'sub' がシステム パスにありません。

次のケースを考慮してください。

  1. app.exe は LoadLibrary( "sub/regular.dll" ) を呼び出します。ドキュメントに記載されている DLL 検索手順と一致して、Windows が helper.dll を見つけることができないため、これは失敗します。
  2. app.exe は CoCreateInstance を呼び出して、com_server.dll に実装されたオブジェクトを作成します。これは成功し、helper.dll がロードされます。

主な質問: ケース 2 が機能するのはなぜですか? COM サーバーの場合の依存 DLL 検索手順の詳細は?

CoCreateInstance で com オブジェクトを作成すると、実装している dll のフォルダーが何らかの形で依存関係の検索パスに追加されているように見えます。これは起こっていることであり、これは保証されていますか? このケースについて説明しているドキュメントはどこにも見つかりません。

4

1 に答える 1

0

MSDN の LoadLibraryのドキュメントを見てみましょう。

文字列が完全なパスを指定する場合、関数はモジュールのそのパスのみを検索します。文字列が相対パスまたはパスなしのモジュール名を指定する場合、関数は標準の検索戦略を使用してモジュールを検索します。詳細については、備考を参照してください。

わかりました、これで上記の #1 の動作が説明されました。あなたが言った場合:

LoadLibrary("C:\\program files\\AppFolder\\Sub\\com_server.dll")

その後、依存する DLL が検出され、LoadLibrary は成功します。

#2 で COM がどのように成功するかについては、com_server.dll が InProcServer32 キーのレジストリにどのように登録されているかに大きく依存します。ファイルへのフル パスの場合、LoadLibrary は上記のように機能します。それが相対パスである場合、COM はあなたのような DLL を見つけるためにさまざまなことを行っているのではないかと思います。

考えられる可能性の 1 つは、CoCreateInstance がLOAD_LIBRARY_SEARCH_DLL_LOAD_DIRフラグを設定してLoadLibraryExを呼び出していることです。異なるフラグの組み合わせで LoadLibrary(Ex) を複数回呼び出すことさえあります。

また、CoCreateInstance がシステム API であることを考えると、別の検索パスを可能にする非公開の内部バージョンの LoadLibrary を持っている可能性は十分にあります。

于 2012-12-19T06:37:16.303 に答える