переопределение @executable_path в DLL, загруженной с помощью dlopen () - PullRequest
7 голосов
/ 23 марта 2011

Операционная система - MacOS X, в частности 10.5 (Leopard) на PowerPC G4, но у меня такая же проблема на x86 под управлением 10.6.

Я пишу приложение, которое динамически загружает DLL. DLL (назовем это foo.dylib) является частью другого приложения, расположенного в другом месте на жестком диске; мое приложение находит foo.dylib программно (точное расположение может измениться, возможно, пользователь определяет путь к 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, но это должно быть сделано до запуска моего приложения (эта переменная среды читается динамическим компоновщиком только один раз; изменяя его значение программно с setenv() или putenv() не имеет никакого эффекта). Это несовместимо с динамическим обнаружением местоположения файла foo.dylib.

Есть ли программный способ переопределить эффект @executable_path?

Ответы [ 2 ]

6 голосов
/ 24 марта 2011

Из прочтения источника dyld (ищите @executable_path) я бы сказал, что ответ однозначно "нет".@executable_path заменяется основным путем к исполняемому файлу, который хранится в виде глобальной строки в модуле dyld.

И да, ваше подозрение верное, dyld читает и сохраняет переменные окружения при запуске, так что вы можете 'изменить их на лету (вы можете искать тот же исходный файл, который я связал для DYLD_LIBRARY_PATH).Вы могли бы иметь приложение-заглушку, которое устанавливает переменные среды и затем запускает ваше реальное приложение.Здесь Dyld не предлагает вам много решений, он не предназначен для того, чтобы давать вам ссылки в произвольных частных сторонних библиотеках.

2 голосов
/ 07 июня 2011

если вы поддерживаете OtherApp, вы можете использовать @loader_path вместо @executable_path для поиска зависимостей: @loader_path всегда разрешает путь к модулю (т. Е. К библиотеке или исполняемому файлу), который требует загрузки библиотеки, поэтому рекурсивные зависимости всегда найдены.

Доступно для Mac Os 10.5 и более поздних версий.
См. "Man dyld" для получения подробной информации.

Другим вариантом будет dlopen использование зависимостей перед основной библиотекой.

...