Błąd Linux C ++: niezdefiniowane odwołanie do „dlopen”

147

Pracuję w Linuksie z C ++ (Eclipse) i chcę korzystać z biblioteki. Eclipse pokazuje mi błąd:

undefined reference to 'dlopen' 

Czy znasz rozwiązanie?

Oto mój kod:

#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);
}
user101375
źródło

Odpowiedzi:

254

Musisz połączyć się z libdl, dodaj

-ldl

do opcji konsolidatora

Masci
źródło
2
Napotkałem ten sam problem ... Dodałem flagę kompilatora w obszarze Projekt> Właściwości> Kompilacja C / C ++> Ustawienia> (Mój konsolidator)> Różne w polu tekstowym Flagi konsolidatora. To nic nie dało.
MirroredFate
3
Ha, ok, dla każdego, kto ma ten problem, skorzystaj z powyższej ścieżki, z wyjątkiem przejdź do Biblioteki, a nie Różne i dodaj 'dl'
MirroredFate
2
Ta odpowiedź pomogła. Dla każdego, kto chce znaleźć lokalizację libdl.so, po prostu przejdź do katalogu głównego i wpiszlocate libdl.so
Nav
Odpowiedź MirroredFate również zadziałała dla mnie. Nie rozumiem jednak dlaczego; każda inna biblioteka, jaką kiedykolwiek musiałem połączyć, działała po umieszczeniu w Różne.
aggregate1166877
75

@Masci jest poprawne, ale jeśli używasz C (i gcckompilatora), weź pod uwagę, że to nie działa:

gcc -ldl dlopentest.c

Ale to robi:

gcc dlopentest.c -ldl

Trochę mi zajęło, żeby się zorientować ...

knocte
źródło
2
Odkryłem, że kolejność opcji też ma znaczenie. W projekcie używającym sqlite3, muszę wstawić -ldl (i -lpthread) po -lsqlite3. Nie wiem, co to jest, jestem pewien, że odpowiedź jest, gdybym tylko RTFM.
O cholera, to wszystko! Nigdy bym nie zgadł, że stawianie opcji na pierwszym miejscu (co ma dla mnie więcej sensu) nie działa, a umieszczanie ich po nie. Dziękuję @knocte!
Joe Strout
@ user2918461 uderzył w gwóźdź w głowę. Musiałem ustawić -l w „prawidłowej” kolejności.
NDEthos
tak, miło mieć, ale nie jest to priorytet w pisaniu odpowiedzi, aby pomóc jak największej liczbie ludzi w odpowiednim czasie
knocte
8

Temat jest dość stary, ale walczyłem z tym samym problemem dzisiaj podczas kompilacji cegui 0.7.1 (warunek wstępny openVibe).

U mnie zadziałało ustawienie: LDFLAGS="-Wl,--no-as-needed" w pliku Makefile.

Próbowałem zostały również -ldldla LDFLAGSale bezskutecznie.

sprośny
źródło
8

to nie działa:

gcc -ldl dlopentest.c

Ale to robi:

gcc dlopentest.c -ldl

To z pewnością jedna irytująca „funkcja”

Miałem z tym problem podczas pisania składni heredoc i znalazłem kilka interesujących faktów . Ze CC=Clangto działa:

$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

a także wszystkie te:

  • $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

Jednak CC=gccdziała tylko ostatni wariant; -ldlpo -(symbol argumentu stdin).

wulkaniczny kruk
źródło
5

możesz spróbować to dodać

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

do opcji konfiguracyjnych

user2948547
źródło
1
Użycie zmiennej LIBS pomogło mi przy konfiguracji, która umieściła -ldl we właściwym miejscu w linii poleceń.
duncan
5

Używałem CMake do kompilacji mojego projektu i napotkałem ten sam problem.

Rozwiązanie opisane tutaj działa jak urok, po prostu dodaj $ {CMAKE_DL_LIBS} do wywołania target_link_libraries ()

Lucas Coelho
źródło
1
Dzięki! To też mi pomogło. Ale dopiero po zmianie kompilatora na clang SET(CMAKE_CXX_COMPILER /usr/bin/clang++). Z / usr / bin / c ++ na moim Ubuntu to nie działało ... (zobacz także odpowiedź Vulcan Raven)
thomasfermi
3

Musiałeś zrobić coś takiego dla makefile:

LDFLAGS='-ldl'
make install

Spowoduje to przekazanie flag konsolidatora od producenta do konsolidatora. Nie ma znaczenia, że ​​plik makefile został wygenerowany automatycznie.

Obrabować
źródło
1

Napotkałem ten sam problem, nawet używając -ldl.

Poza tą opcją, pliki źródłowe muszą być umieszczane przed bibliotekami, zobacz niezdefiniowane odniesienie do `dlopen ' .

Deqing
źródło
1

Aby użyć funkcji dl, musisz użyć opcji -ldl dla konsolidatora.

jak to robisz w zaćmieniu?

Naciśnij Projekt -> Właściwości -> Kompilacja C / C ++ -> Ustawienia -> Linker GCC C ++ ->
Biblioteki -> w polu „Biblioteki (-l)” naciśnij znak „+” -> napisz " dl " (bez cudzysłowów) -> naciśnij ok -> wyczyść i odbuduj swój projekt.

Amitk
źródło
1
 $gcc -o program program.c -l <library_to_resolve_program.c's_unresolved_symbols>

Dobry opis, dlaczego położenie -l dl ma znaczenie

Ale jest też dość zwięzłe wyjaśnienie w dokumentach 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.
flerb
źródło