Переписанный вопрос (хотя он уже решен):
У меня были проблемы с использованием dlopen (3) для загрузки библиотеки общих объектов в Linux. Библиотека является частью системы библиотек, созданных мной, которые все загружаются во время выполнения центральным исполняемым файлом. Все это организовано в единую рабочую область в Code :: Blocks, где каждому проекту предоставляется собственная папка в каталоге с именем Source, который должен поставляться вместе с программой. Каталог сборки исполняемого файла — это два каталога в обратном направлении от его собственного исходного кода, так что исполняемая и исходная папки находятся в одном каталоге. Библиотеки также собираются в тот же каталог, что и исполняемый файл, поэтому, естественно, я передаю имя библиотеки Я пытаюсь открыть как показано:
int main(int argc, char** argv) {
void* hLibrary = dlopen("libLibrary.so", RTLD_NOW | RTLD_GLOBAL);
if(hLibrary == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
return 0;
}
Это работало в один момент, когда каталог сборки был таким же, как исходный код, пока я не изменил каталоги исходного кода в соответствии с расположением, описанным выше. Проблема на этом этапе заключается в том, что dlerror () возвращает «Не удается открыть libLibrary.so: нет такого файла или каталога», даже если файл явно существует и находится в том же каталоге, что и исполняемый файл. Затем я попытался передать файл «/libLibrary.so», потому что, согласно man-странице dlopen (3), добавление / указывает на относительный каталог. Это вернуло ту же ошибку.
Решением этой проблемы было то, что «./» было необходимо — где «.» представляет рабочий каталог исполняемого файла — и рабочий каталог необходимо изменить в Code :: Blocks туда, где должен быть построен исполняемый файл. Следующее работает отлично:
void* hLibrary = dlopen("./libLibrary.so", RTLD_NOW | RTLD_GLOBAL);
Это не совсем полное решение, но следующее в основном эквивалентно тому, что я делаю:
void* hLibrary = dlopen("./../../libLibrary.so", RTLD_NOW | RTLD_GLOBAL);
Надеюсь, это немного лучше объясняет ситуацию.
Прочитайте dlopen (3) страница руководства (например, набрав man dlopen
в терминале на вашей машине):
Если имя файла содержит косую черту («/»), то оно
интерпретируется как (относительный или абсолютный) путь. В противном случае
динамический компоновщик ищет библиотеку следующим образом (см. ld.so (8) для
Более подробная информация):
o (ELF only) If the executable file for the calling program
contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag,
then the directories listed in the DT_RPATH tag are searched.
o If, at the time that the program was started, the environment
variable LD_LIBRARY_PATH was defined to contain a colon-separated
list of directories, then these are searched. (As a security
measure this variable is ignored for set-user-ID and set-group-ID
programs.)
o (ELF only) If the executable file for the calling program
contains a DT_RUNPATH tag, then the directories listed in that
tag are searched.
o The cache file /etc/ld.so.cache (maintained by ldconfig(8)) is
checked to see whether it contains an entry for filename.
o The directories /lib and /usr/lib are searched (in that order).
Так что вам нужно позвонить dlopen("./libLibraryName.so", RTLD_NOW)
-не просто dlopen("libLibraryName.so", RTLD_NOW)
который хочет, чтобы ваш плагин был в вашем $LD_LIBRARY_PATH
на в /usr/lib/
и т.д …. — или добавить .
на ваш LD_LIBRARY_PATH
(который я не рекомендую по соображениям безопасности).
Как Джоннаш ответил Вы должны использовать и отображать результат dlerror
когда dlopen
(или же dlsym
) не удается:
void* dlh = dlopen("./libLibraryName.so", RTLD_NOW);
if (!dlh)
{ fprintf(stderr, "dlopen failed: %s\n", dlerror());
exit(EXIT_FAILURE); };
Вы могли бы хотеть прочитать некоторые книги как Расширенное программирование в Linux получить некоторые знания о системном программировании Linux в целом.
О dlopen определено; Ошибка dlopen динамической библиотеки может быть проверено. Неопределенный символ ошибка этим ссылка на сайт.