Question

Le système d'exploitation est MacOS X, plus précisément 10.5 (Leopard) sur un PowerPC G4, mais j'ai le même problème sur un x86 exécutant 10.6.

J'écris une application qui charge dynamiquement une DLL. La DLL (appelons-la foo.dylib) fait partie d'une autre application, située ailleurs sur le disque dur; mon application trouve foo.dylib par programme (l'emplacement exact peut changer, peut-être l'utilisateur désigne le chemin de la DLL via une interface graphique à partir de l'application en cours d'exécution elle-même). Par exemple, supposons que mon application se trouve dans le répertoire /Application/MyApp.app/Contents/MacOS et que foo.dylib se trouve être dans /Application/OtherApp.app/Contents/MacOS. Le chargement de DLL utilise dlopen().

Maintenant, il s'avère que foo.dylib lui-même a besoin d'un tas d'autres DLL, qui sont dans le même répertoire, mais dont je ne sais rien à l'avance. Chacune de ces DLL supplémentaires est enregistrée dans foo.dylib avec un chemin tel que @executable_path/bar.dylib. La sémantique de @executable_path est qu'il doit être remplacé par le répertoire dans lequel l'exécutable du processus actuel a été trouvé. Cela fonctionne très bien pour OtherApp, pas pour moi: quand j'ouvre foo.dylib, il essaie de charger bar.dylib, et il le recherche dans /Application/MyApp.app/Contents/MacOS/bar.dylib, qui n'est pas le bon répertoire.

Une solution de contournement consiste à définir la variable d'environnement DYLD_FALLBACK_LIBRARY_PATH sur /Application/OtherApp.app/Contents/MacOS, mais cela doit être fait avant de lancer mon application (cette variable d'environnement n'est lue qu'une seule fois par l'éditeur de liens dynamique; en changeant sa valeur par programme avec setenv() ou putenv() n'a aucun effet). Ceci n'est pas compatible avec la découverte dynamique de l'emplacement du fichier foo.dylib.

Existe-t-il un moyen par programmation de remplacer l'effet de @executable_path?

Était-ce utile?

La solution

En lisant la source dyld (search for @executable_path), je dirais que la réponse est sans équivoque "non".@executable_path est remplacé par le chemin de l'exécutable principal, qui est stocké sous forme de chaîne globale dans le module dyld.

Et oui, votre suspicion est correcte, dyld lit et enregistre ses variables d'environnement au démarrage, vous ne pouvez donc pas les changer à la volée (vous pouvez rechercher ce même fichier source que j'ai lié pour DYLD_LIBRARY_PATH).Vous pouvez avoir une application stub qui définit les variables d'environnement, puis lance votre application réelle.dyld ne vous offre pas beaucoup de solutions ici, il n'est pas vraiment conçu pour vous permettre de créer des liens dans des bibliothèques tierces privées arbitraires.

Autres conseils

si vous maintenez OtherApp, vous pouvez utiliser @loader_path au lieu de @executable_path pour localiser les dépendances: @loader_path se résout toujours au chemin du module (c'est-à-dire bibliothèque ou exécutable) qui nécessite de charger la bibliothèque, donc des dépendances récursives sont toujours trouvées.

Ceci est disponible à partir de Mac OS 10.5.
Voir «man dyld» pour des informations détaillées.

Une autre option consisterait à générer des dépendances de codage générique avant la bibliothèque principale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top