Domanda

Il sistema operativo è macOS X, in particolare 10.5 (leopardo) su un powerPC G4, ma ho lo stesso problema su un X86 in esecuzione 10.6.

Sto scrivendo un'applicazione che carica dinamicamente una DLL. La DLL (chiamiamolo foo.dylib) fa parte di un'altra applicazione, situata altrove sul harddisk; La mia applicazione trova foo.dylib programmaticamente (la collocazione esatta può cambiare, possibilmente l'utente designa il percorso DLL attraverso una GUI dall'applicazione in esecuzione stessa). Ad esempio, supponiamo che la mia domanda si trovi nella directory /Application/MyApp.app/Contents/MacOS, e foo.dylib capita di essere /Application/OtherApp.app/Contents/MacOS. Usi di caricamento DLL dlopen().

Ora, si scopre foo.dylib stesso ha bisogno di un mucchio di altre DLL, che sono nella stessa directory, ma di cui non so nulla in anticipo. Ogni DLL extra è registrata in foo.dylib con un percorso come @executable_path/bar.dylib. La semantica di @executable_path sono che dovrebbe essere sostituito dalla directory in cui è stato trovato l'eseguibile del processo corrente. Funziona alla grande per altropp, non per me: quando apro foo.dylib, cerca di caricare bar.dylib, e lo cerca dentro /Application/MyApp.app/Contents/MacOS/bar.dylib, che non è la directory giusta.

Una soluzione alternativa è impostare il DYLD_FALLBACK_LIBRARY_PATH Ambiente variabile a /Application/OtherApp.app/Contents/MacOS, ma questo deve essere fatto prima Avvio della mia applicazione (quella variabile di ambiente è lettura solo una volta dal linker dinamico; modificando il suo valore programmaticamente con setenv() o putenv() non ha alcun effetto). Questo non è compatibile con la scoperta dinamica della posizione del foo.dylib file.

Esiste un modo programmatico per sovrascrivere l'effetto di @executable_path ?

È stato utile?

Soluzione

Dalla lettura del fonte dyld (Cerca @executable_path), direi che la risposta è inequivocabilmente "no". @Executable_Path viene sostituito con il percorso eseguibile principale, che viene archiviato come una stringa globale nel modulo Dyld.

E sì, il tuo sospetto è corretto, Dyld legge e salva le sue variabili di ambiente all'avvio, quindi non puoi cambiarle al volo (puoi cercare lo stesso file di origine che ho collegato per Dyld_Library_Path). Potresti avere un'applicazione stub che imposta le variabili di ambiente e quindi lancia la tua vera applicazione. Dyld non ti offre molte soluzioni qui, non è davvero progettato per consentirti di collegare in librerie arbitrarie di terze parti private.

Altri suggerimenti

Se mantieni altro, è possibile utilizzare @Loader_Path invece di @Executable_Path per individuare le dipendenze: @loader_Path Risolvi sempre sul percorso del modulo (IE libreria o eseguibile) che richiede di caricare la libreria, quindi le dipendenze ricorsive si trovano sempre.

Questo è disponibile da Mac OS 10.5 in poi.
Vedi "Man Dyld" per informazioni dettagliate.

Un'altra opzione sarebbe dlopendipendenze prima della biblioteca principale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top