Linux c ++ Fehler: undefinierter Verweis auf 'dlopen'


147

Ich arbeite unter Linux mit C ++ (Eclipse) und möchte eine Bibliothek verwenden. Eclipse zeigt mir einen Fehler:

undefined reference to 'dlopen' 

Kennen Sie eine Lösung?

Hier ist mein Code:

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

Antworten:


254

Sie müssen gegen libdl verlinken, hinzufügen

-ldl

zu Ihren Linker-Optionen


2
Ich bin auf dasselbe Problem gestoßen ... Ich habe das Compiler-Flag unter Projekt> Eigenschaften> C / C ++ Build> Einstellungen> (Mein Linker)> Verschiedenes im Textfeld Linker-Flags hinzugefügt. Es hat nichts getan.
MirroredFate

3
Ha, ok, für alle anderen, die dieses Problem haben, verwenden Sie den obigen Pfad, außer gehen Sie zu Bibliotheken und nicht zu Verschiedenes und fügen Sie das 'dl'
MirroredFate

2
Diese Antwort hat geholfen. Für alle, die den Speicherort von libdl.so finden möchten, gehen Sie einfach in das Stammverzeichnis und geben Sielocate libdl.so
Nav

Die Antwort von MirroredFate hat auch bei mir funktioniert. Ich verstehe aber nicht warum; Jede andere Bibliothek, die ich jemals verlinken musste, funktionierte, wenn sie in Verschiedenes platziert wurde.
Aggregat1166877

75

@Masci ist korrekt, aber falls Sie C (und den gccCompiler) verwenden, berücksichtigen Sie, dass dies nicht funktioniert:

gcc -ldl dlopentest.c

Aber das tut:

gcc dlopentest.c -ldl

Ich habe ein bisschen gebraucht, um herauszufinden ...


2
Ich habe festgestellt, dass auch die Reihenfolge der Optionen von Bedeutung ist. Bei einem Projekt mit sqlite3 muss ich -ldl (und -lpthread) nach -lsqlite3 setzen. Ich weiß nicht, was das ist, ich bin sicher, die Antwort ist da, wenn ich nur RTFM würde.

Heiliger Mist, das war's! Ich hätte nie gedacht, dass es nicht funktioniert, die Optionen an die erste Stelle zu setzen (was für mich sinnvoller ist), während sie danach stehen. Vielen Dank, @knocte!
Joe Strout

@ user2918461 traf den Nagel auf den Kopf. Ich musste die -l's in die "richtige" Reihenfolge bringen.
NDEthos

Ja, schön zu haben, aber keine Priorität für das Schreiben der Antwort, um so vielen Menschen wie möglich rechtzeitig zu helfen
Knocte

8

Das Thema ist ziemlich alt, aber ich hatte heute beim Kompilieren von cegui 0.7.1 (openVibe-Voraussetzung) mit demselben Problem zu kämpfen.

Was für mich funktioniert hat war zu setzen: LDFLAGS="-Wl,--no-as-needed" im Makefile.

Ich habe auch versucht , -ldlfür , LDFLAGSaber ohne Erfolg.


8

das funktioniert nicht:

gcc -ldl dlopentest.c

Aber das tut:

gcc dlopentest.c -ldl

Das ist sicher eine nervige "Funktion"

Ich hatte Probleme damit, Heredoc-Syntax zu schreiben, und fand einige interessante Fakten . Mit CC=Clangfunktioniert das:

$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

sowie alle diese:

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

Mit CC=gccfunktioniert jedoch nur die letzte Variante; -ldlafter -(das stdin-Argument-Symbol).


5

Sie können versuchen, dies hinzuzufügen

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

zu den Konfigurationsoptionen


1
Die Verwendung der LIBS-Variablen hat bei mir funktioniert, um die Konfiguration so zu gestalten, dass -ldl an der richtigen Stelle in der Befehlszeile platziert wird.
Duncan

5

Ich habe CMake zum Kompilieren meines Projekts verwendet und das gleiche Problem festgestellt.

Die hier beschriebene Lösung funktioniert wie ein Zauber. Fügen Sie einfach $ {CMAKE_DL_LIBS} zum Aufruf von target_link_libraries () hinzu


1
Vielen Dank! Das hat mir auch geholfen. Aber erst nachdem ich meinen Compiler auf Clang geändert habe SET(CMAKE_CXX_COMPILER /usr/bin/clang++). Mit / usr / bin / c ++ auf meinem Ubuntu funktionierte es nicht ... (siehe auch die Antwort des vulkanischen Raben)
thomasfermi

3

Sie mussten so etwas für das Makefile tun:

LDFLAGS='-ldl'
make install

Dadurch werden die Linker-Flags von make bis zum Linker weitergeleitet. Es spielt keine Rolle, dass das Makefile automatisch generiert wurde.



1

Um dl-Funktionen verwenden zu können, müssen Sie das Flag -ldl für den Linker verwenden.

Wie machst du das in Eclipse?

Klicken Sie auf Projekt -> Eigenschaften -> C / C ++ - Build -> Einstellungen -> GCC C ++ Linker ->
Bibliotheken -> im Feld "Bibliotheken (-l)" auf das Zeichen "+" -> Schreiben " dl " (ohne Anführungszeichen) -> OK drücken -> Projekt bereinigen und neu erstellen.


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

Eine gute Beschreibung, warum die Platzierung von -l dl wichtig ist

Aber es gibt auch eine ziemlich prägnante Erklärung in den Dokumenten von $ 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.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.