8

オペレーティング システムは MacOS X、具体的には PowerPC G4 上の 10.5 (Leopard) ですが、10.6 を実行している x86 でも同じ問題があります。

DLL を動的にロードするアプリケーションを作成しています。DLL (これを と呼びましょうfoo.dylib) は別のアプリケーションの一部であり、ハードディスクの別の場所にあります。私のアプリケーションはプログラムで見つけfoo.dylibます(正確な配置は変更される可能性があり、おそらくユーザーは実行中のアプリケーション自体からGUIを介してDLLパスを指定します)。たとえば、アプリケーションがディレクトリ/Application/MyApp.app/Contents/MacOSにあり、foo.dylibたまたま にあるとし/Application/OtherApp.app/Contents/MacOSます。DLL の読み込みにはdlopen().

さて、それfoo.dylib自体が同じディレクトリにある他のDLLの束を必要としていることがわかりましたが、事前に何も知りません。このような追加の DLL はそれぞれ、.foo.dylibなどのパスで登録され@executable_path/bar.dylibます。のセマンティクスは@executable_path、現在のプロセス実行可能ファイルが見つかったディレクトリに置き換える必要があるということです。これは、私ではなく、OtherApp でうまく機能します。 を開くfoo.dylibと、 をロードしようとし、正しいディレクトリではないbar.dylibで検索します。/Application/MyApp.app/Contents/MacOS/bar.dylib

DYLD_FALLBACK_LIBRARY_PATH回避策は、環境変数をに設定することですが、これはアプリケーションを起動する前/Application/OtherApp.app/Contents/MacOSに行う必要があります (この環境変数はダイナミック リンカーによって 1 回だけ読み取られます。プログラムで値を変更しても効果はありません)。これは、ファイルの場所の動的検出と互換性がありません。setenv()putenv()foo.dylib

の効果をオーバーライドするプログラム的な方法はあります@executable_pathか?

4

2 に答える 2

6

dyld ソース(@executable_path を検索) を読むと、答えは明確に「いいえ」です。@executable_path は、グローバル文字列として dyld モジュールに格納されているメインの実行可能パスに置き換えられます。

はい、あなたの疑いは正しいです。dyld は起動時に環境変数を読み取って保存するため、その場で変更することはできません (DYLD_LIBRARY_PATH にリンクした同じソース ファイルを検索できます)。環境変数を設定して実際のアプリケーションを起動するスタブ アプリケーションを作成できます。dyld はここで多くのソリューションを提供しません。実際には、任意のプライベート サードパーティ ライブラリにリンクできるように設計されているわけではありません。

于 2011-03-24T12:24:47.253 に答える
2

OtherApp を維持する場合、 @executable_path の代わりに @loader_path を使用して依存関係を見つけることができます。

これは、Mac Os 10.5 以降で利用できます。
詳細については、「man dyld」を参照してください。

別のオプションは、dlopenメイン ライブラリの前に依存関係を指定することです。

于 2011-06-07T08:58:12.280 に答える