Ошибка Linux c ++: неопределенная ссылка на «dlopen»


147

Я работаю в Linux с C ++ (Eclipse) и хочу использовать библиотеку. Затмение показывает мне ошибку:

undefined reference to 'dlopen' 

Вы знаете решение?

Вот мой код:

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
    void *handle;
    double (*desk)(char*);
    char *error;

    handle = dlopen ("/lib/CEDD_LIB.so.6", RTLD_LAZY);
    if (!handle) {
        fputs (dlerror(), stderr);
        exit(1);
    }

    desk= dlsym(handle, "Apply");

    if ((error = dlerror()) != NULL)  {
        fputs(error, stderr);
        exit(1);
    }

    dlclose(handle);
}

Ответы:


254

Вы должны сделать ссылку на libdl, добавить

-ldl

к вашим параметрам компоновщика


2
Я столкнулся с той же проблемой ... Я добавил флаг компилятора в Project> Properties> C / C ++ Build> Settings> (My Linker)> Miscellaneous в текстовом поле Linker flags. Ничего не сделал
MirroredFate

3
Ха, хорошо, для всех, у кого есть эта проблема, используйте вышеуказанный путь, за исключением того, что идите в Библиотеки, а не Разное и добавьте 'dl'
MirroredFate

2
Этот ответ помог. Для тех, кто хочет найти местоположение libdl.so, просто перейдите в корневой каталог и введитеlocate libdl.so
Nav

Ответ MirroredFate сработал и для меня. Я не понимаю почему, хотя; любая другая библиотека, с которой мне когда-либо приходилось ссылаться, работала, когда помещалась в Разное.
aggregate1166877

75

@Masci корректен, но в случае, если вы используете C (и gccкомпилятор), учтите, что это не работает:

gcc -ldl dlopentest.c

Но это делает:

gcc dlopentest.c -ldl

Мне понадобилось немного, чтобы понять ...


2
Я обнаружил, что порядок опций тоже имеет значение. В проекте, использующем sqlite3, я должен поставить -ldl (и -lpthread) после -lsqlite3. Не знаю, что это, я уверен, что ответ есть, если бы я просто RTFM.

Святое дерьмо, вот и все! Я бы никогда не догадался, что сначала поставить опции (что для меня более логично) не работает, а поставить после. Спасибо, @knocte!
Джо Струт

@ user2918461 ударил ногтем по голове. Я должен был поставить -l в "правильном" порядке.
NDEthos

да, приятно иметь, но не приоритет для написания ответа, чтобы помочь как можно
большему

8

Тема довольно старая, но сегодня я боролся с той же проблемой при компиляции cegui 0.7.1 (обязательное условие openVibe).

То, что работало для меня, должно было установить: LDFLAGS="-Wl,--no-as-needed" в Makefile.

Я также пытался -ldlдля , LDFLAGSно безрезультатно.


8

это не работает:

gcc -ldl dlopentest.c

Но это делает:

gcc dlopentest.c -ldl

Это одна раздражающая «особенность» наверняка

Я боролся с этим, когда писал синтаксис heredoc, и нашел несколько интересных фактов . С CC=Clangэтим работает:

$CC -ldl -x c -o app.exe - << EOF
#include <dlfcn.h>
#include <stdio.h>
int main(void)
{
  if(dlopen("libc.so.6", RTLD_LAZY | RTLD_GLOBAL))
    printf("libc.so.6 loading succeeded\n");
  else
    printf("libc.so.6 loading failed\n");
  return 0;
}
EOF

./app.exe

а также все это:

  • $CC -ldl -x c -o app.exe - << EOF
  • $CC -x c -ldl -o app.exe - << EOF
  • $CC -x c -o app.exe -ldl - << EOF
  • $CC -x c -o app.exe - -ldl << EOF

Однако, с CC=gcc, работает только последний вариант; -ldlпосле -(символ аргумента стандартного ввода).


5

Вы можете попробовать добавить это

LIBS=-ldl CFLAGS=-fno-strict-aliasing

к настройке параметров


1
Использование переменной LIBS помогло мне настроить файл -ldl в нужном месте командной строки.
Дункан

5

Я использовал CMake для компиляции своего проекта, и я нашел ту же проблему.

Описанное здесь решение работает как чудо, просто добавьте $ {CMAKE_DL_LIBS} к вызову target_link_libraries ()


1
Спасибо! Это помогло мне также. Но только после того, как я изменил свой компилятор на Clang SET(CMAKE_CXX_COMPILER /usr/bin/clang++). С / usr / bin / c ++ на моем Ubuntu он не работал ... (см. Также ответ
вулканского

3

Вам нужно было сделать что-то подобное для make-файла:

LDFLAGS='-ldl'
make install

Это передаст флаги компоновщика от make до компоновщика. Не имеет значения, что make-файл был сгенерирован автоматически.



1

Чтобы использовать функции dl, необходимо использовать флаг -ldl для компоновщика.

как ты делаешь это в затмении?

Нажмите Project -> Properties -> C / C ++ build -> Settings -> GCC C ++ Linker ->
Libraries -> в поле «Libraries (-l)» нажмите знак «+» -> write " DL " (без кавычек) -> нажмите ОК -> очистить и восстановить свой проект.


1
 $gcc -o program program.c -l <library_to_resolve_program.c's_unresolved_symbols>

Хорошее описание того, почему размещение -l dl имеет значение

Но в документах From $ man gcc также есть довольно краткое объяснение.

   -llibrary
   -l library
       Search the library named library when linking.  (The second
       alternative with the library as a separate argument is only for POSIX
       compliance and is not recommended.)
       It makes a difference where in the command you write this option; the
       linker searches and processes libraries and object files in the order
       they are specified.  Thus, foo.o -lz bar.o searches library z after
       file foo.o but before bar.o.  If bar.o refers to functions in z,
       those functions may not be loaded.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.