Помилка c ++ Linux: невизначене посилання на '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, додати

-лдл

до варіантів вашого лінкера


2
Я зіткнувся з тією ж проблемою ... Я додав прапор компілятора в розділі Проект> Властивості> C / C ++ Build> Налаштування> (Мій Linker)> Різне в текстовому полі прапорців Linker. Це нічого не зробило.
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

так, приємно мати, але не пріоритет для написання відповіді, щоб вчасно допомогти якомога більшої кількості людей
knocte

8

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

Що для мене працювало - це встановити: LDFLAGS="-Wl,--no-as-needed" у Makefile.

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


8

це не працює:

gcc -ldl dlopentest.c

Але це робить:

gcc dlopentest.c -ldl

Це одна дратівлива "особливість" точно

Я з цим боровся, коли писав синтаксис гередок і знаходив кілька цікавих фактів . З 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, працює лише останній варіант; -ldlafter -(символ аргументу stdin).


5

ви можете спробувати додати це

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

до параметрів налаштування


1
Використання змінної LIBS працювало для мене, щоб отримати конфігурацію, щоб поставити -ldl в потрібне місце в командному рядку.
duncan

5

Я використовував CMake для складання свого проекту, і я виявив ту саму проблему.

Описане тут рішення працює як шарм, просто додайте $ {CMAKE_DL_LIBS} у виклик target_link_libraries ()


1
Дякую! Це мені теж допомогло. Але лише після того, як я змінив компілятор на кланг SET(CMAKE_CXX_COMPILER /usr/bin/clang++). З / usr / bin / c ++ на моєму Ubuntu він не працював ... (див. Також відповідь вулкана-ворона)
thomasfermi

3

Вам потрібно було зробити щось подібне для makefile:

LDFLAGS='-ldl'
make install

Це передасть прапорці лінкера від make через до Linker. Не має значення, що makefile був автоматично створений.



1

Для використання функцій dl потрібно використовувати прапор -ldl для лінкера.

як ти це робиш у затемненні?

Натисніть Project -> Властивості -> C / C ++ build -> Settings -> GCC C ++ Linker ->
Libraries -> у полі "Бібліотеки (-l)" натисніть знак "+" -> write " dl " (без лапок) -> натисніть ok -> очистіть і відновіть проект.


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

Хороший опис того, чому має значення розміщення –l dl

Але в документах від $ 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.