dlopen()がロードされたdllで@executable_pathをオーバーライドする
-
28-10-2019 - |
質問
オペレーティングシステムはMACOS X、特にPowerPC G4で10.5(ヒョウ)ですが、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
現在のプロセス実行可能ファイルが見つかったディレクトリに置き換える必要があるということです。これは私にとってではなく、他のAPPに最適です:私が開くとき foo.dylib
, 、ロードしようとします bar.dylib
, 、それを探します /Application/MyApp.app/Contents/MacOS/bar.dylib
, 、これは適切なディレクトリではありません。
回避策は、を設定することです DYLD_FALLBACK_LIBRARY_PATH
環境変数へ /Application/OtherApp.app/Contents/MacOS
, 、しかし、これは行われなければなりません 前 私のアプリケーションを起動します(その環境変数はダイナミックリンカーによって一度だけ読み取りされます。その値をプログラムで変更する setenv()
また putenv()
効果はありません)。これは、の場所の動的な発見と互換性がありません foo.dylib
ファイル。
の効果をオーバーライドするプログラム的な方法はありますか @executable_path
?
解決
読むことから dyld source (@executable_pathを検索)、答えは明確に「いいえ」だと思います。 @executable_pathは、dyldモジュールにグローバル文字列として保存されているメイン実行可能パスに置き換えられます。
そして、はい、あなたの疑いは正しいです、Dyldはスタートアップで環境変数を読み取り、保存するので、その場でそれらを変更することはできません(dyld_library_pathにリンクした同じソースファイルを検索できます)。環境変数を設定し、実際のアプリケーションを起動するスタブアプリケーションを使用できます。ここでは、Dyldは多くのソリューションを提供していません。任意のプライベートサードパーティライブラリにリンクできるように設計されていません。
他のヒント
他のAPPを維持する場合は、 @executable_pathの代わりに@loader_pathを使用して依存関係を特定できます。
これは、Mac OS 10.5以降から入手できます。
詳細については、「Man Dyld」を参照してください。
別のオプションはそうです dlopen
メインライブラリの前の依存関係。