Errore c ++ Linux: riferimento indefinito a 'dlopen'


147

Lavoro in Linux con C ++ (Eclipse) e voglio usare una libreria. Eclipse mi mostra un errore:

undefined reference to 'dlopen' 

Conosci una soluzione?

Ecco il mio codice:

#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);
}

Risposte:


254

Devi collegarti a libdl, aggiungi

-ldl

alle opzioni del tuo linker


2
Ho riscontrato lo stesso problema ... Ho aggiunto il flag del compilatore in Progetto> Proprietà> Build C / C ++> Impostazioni> (My Linker)> Varie nel campo di testo Flag Linker. Non ha fatto niente.
MirroredFate

3
Ah, ok, per chiunque abbia questo problema, usa il percorso sopra, tranne vai su Librerie piuttosto che Varie e aggiungi il 'dl'
MirroredFate

2
Questa risposta ha aiutato. Per chiunque voglia trovare la posizione di libdl.so, basta andare nella directory principale e digitarelocate libdl.so
Nav

La risposta di MirroredFate ha funzionato anche per me. Non capisco perché, però; ogni altra libreria che abbia mai dovuto collegare funzionava quando veniva inserita in Varie.
aggregate1166877,

75

@Masci è corretto, ma nel caso in cui stai usando C (e il gcccompilatore) tieni presente che questo non funziona:

gcc -ldl dlopentest.c

Ma questo fa:

gcc dlopentest.c -ldl

Mi ha preso un po 'per capire ...


2
Ho scoperto che anche l'ordine delle opzioni conta. Su un progetto che utilizza sqlite3, devo inserire -ldl (e -lpthread) dopo -lsqlite3. Non so cosa sia, sono sicuro che la risposta è lì se volessi semplicemente RTFM.

Santa merda, tutto qui! Non avrei mai immaginato che mettere le opzioni al primo posto (il che ha più senso per me) non funziona, mentre metterle dopo lo fa. Grazie, @knocte!
Joe Strout,

@ user2918461 ha colpito l'unghia sulla testa. Ho dovuto mettere i -l nell'ordine "corretto".
NDEthos,

sì, bello avere, ma non una priorità per scrivere la risposta per aiutare il maggior numero possibile di persone in modo tempestivo
knocte

8

L'argomento è piuttosto vecchio, ma oggi ho lottato con lo stesso problema durante la compilazione di cegui 0.7.1 (prerequisito di openVibe).

Ciò che ha funzionato per me è stato impostare: LDFLAGS="-Wl,--no-as-needed" nel Makefile.

Ho provato anche -ldlper LDFLAGS, ma senza alcun risultato.


8

questo non funziona:

gcc -ldl dlopentest.c

Ma questo fa:

gcc dlopentest.c -ldl

Questa è sicuramente una "caratteristica" fastidiosa

Ho avuto difficoltà con questo quando ho scritto la sintassi ereditaria e ho trovato alcuni fatti interessanti . Con CC=Clang, questo funziona:

$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

così come tutti questi:

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

Tuttavia, con CC=gcc, funziona solo l'ultima variante; -ldlafter -(il simbolo dell'argomento stdin).


5

puoi provare ad aggiungere questo

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

alle opzioni di configurazione


1
L'uso della variabile LIBS ha funzionato per me per ottenere la configurazione per mettere -ldl nel posto giusto sulla riga di comando.
Duncan,

5

Stavo usando CMake per compilare il mio progetto e ho riscontrato lo stesso problema.

La soluzione qui descritta funziona come un incantesimo, è sufficiente aggiungere $ {CMAKE_DL_LIBS} alla chiamata target_link_libraries ()


1
Grazie! Anche questo mi ha aiutato. Ma solo dopo aver cambiato il mio compilatore in clang SET(CMAKE_CXX_COMPILER /usr/bin/clang++). Con / usr / bin / c ++ sul mio Ubuntu non funzionava ... (vedi anche la risposta del corvo vulcaniano)
thomasfermi

3

Dovevi fare qualcosa del genere per il makefile:

LDFLAGS='-ldl'
make install

Ciò passerà i flag del linker dal make through al linker. Non importa che il makefile sia stato generato automaticamente.



1

Per usare le funzioni dl devi usare il flag -ldl per il linker.

come lo fai in eclissi?

Premi Progetto -> Proprietà -> C / C ++ build -> Impostazioni -> GCC C ++ Linker ->
Librerie -> nella casella "Librerie (-l)" premi il segno "+" -> scrivi " dl " (senza virgolette) -> premi ok -> pulisci e ricostruisci il tuo progetto.


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

Una buona descrizione del perché è importante il posizionamento di -l dl

Ma c'è anche una spiegazione piuttosto concisa nei documenti 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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.