Это характерно для твердого кода такие ссылки во время компиляции, и, возможно, обеспечьте параметр командной строки или переменную среды для переопределения значения по умолчанию времени компиляции. Часто программа просто помнит местоположение одного конфигурационного файла (обычно под /etc
) где любые значения по умолчанию времени компиляции могут быть переопределены. Этот подход имеет большую часть смысла для программного обеспечения с открытым исходным кодом, которое компилируется теми же людьми, которые делают операционную систему как часть портов BSD или дистрибутива Linux.
Для приложений, распределенных в двоичной форме, обычный подход должен определить местоположение двоичного файла приложения от своего нулевого аргумента. Условно, нулевой аргумент execve
(т.е. argv[0]
) путь к двоичному файлу (это до вызывающей стороны, часто оболочка, для уважения конвенции). Если argv[0]
не содержит никого /
, приложение должно работать $PATH
поиск на нем.
Я сказал бы, что наиболее распространенное обнаруживает путь, обеспеченный --prefix
. Различные пути могут быть обеспечены различными префиксами, и там являются отдельными для системной конфигурации ("/etc
"), каталог библиотеки ("/usr/lib
") и т.д. в автоинструментах
Инструменты, используемые для компиляции программы, такой как Автоинструменты GNU, могут принять значение --prefix
опция дана и помещенная это в заголовочный файл как определение.
#define PREFIX "/usr/local/"
И в Вашем коде Вы просто использовали бы PREFIX
как часть Ваших путей.
Существует также dladdr()
функция в libc, который возвращает путь к двоичному файлу, в котором указатель заданной функции существует, но:
-rdynamic
чтобы это работало. Я не думаю потребности библиотек это.Для библиотеки Ваши опции намного более ограничены: существует нет argv[0]
таким образом, Ваши опции dladdr()
, или неясный взлом ручного парсинга только для Linux /proc/self/maps
и поиск диапазона адреса памяти, содержащего адрес памяти некоторой библиотеки внутренний символ (например, указатель функции или статическая переменная).
Другие решения я видел в дикой природе:
./configure --prefix=SOME_UNIQUE_VERY_LONG_STRING
, затем при поиске времени установки и замене, что длинная строка в двоичном файле (!!) с /path/to/actual/install/prefix/suffixed/by/enough/slashes//////
и надеюсь, что пользователь никогда ничего не переименовывает в том пути.chroot()
, смонтируйтесь цикл, файловая система FUSE, взломал libc (Проект всплеска), виртуальная машина, и т.д../configure --prefix=..
и затем никогда не звоните chdir()
. Это также повредит вещи, если какие-либо утечки пути из приложения и перейдут к другому приложению, так как другое приложение не сможет правильно разрешить относительный путь.getClass().getProtectionDomain().getCodeSource().getLocation()
, C# имеет Application.StartupPath
среди других большинство языков сценариев имеет некоторый путь.POSIX должен действительно стандартизировать dladdr()
.
Unix Unded, нет никакого портативного способа обнаружить, с которого местоположения был запущен двоичный файл, т.е. переменный префикс установки компилируется в.
$0
). В Python это sys.argv[0]
.
– phunehehe
19.01.2011, 13:27
argv[0]
полный путь.
– ephemient
19.01.2011, 18:47
argv[0]
должен сделать areadlink()
кому:/proc/self/exe
, когда этот файл доступен. Если это перестало работать, то Вы проверяетеargv[0]
и$PATH
. – Juliano 19.01.2011, 17:44/proc/self/exe
другая возможность на Linux, хотя я не уверен, предпочтительно ли это всегда. Если Вы вызываете программу через символьную ссылку,/proc/self/exe
ссылки непосредственно на цель, которая не всегда желательна. – Gilles 'SO- stop being evil' 19.01.2011, 20:28