Erreur Linux C ++: référence non définie à 'dlopen'


147

Je travaille sous Linux avec C ++ (Eclipse), et je souhaite utiliser une bibliothèque. Eclipse me montre une erreur:

undefined reference to 'dlopen' 

Connaissez-vous une solution?

Voici mon 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);
}

Réponses:


254

Vous devez créer un lien avec libdl, ajouter

-ldl

à vos options de l'éditeur de liens


2
J'ai rencontré le même problème ... J'ai ajouté le drapeau du compilateur sous Projet> Propriétés> Construction C / C ++> Paramètres> (Mon éditeur de liens)> Divers dans le champ de texte des indicateurs de l'éditeur de liens. Cela n'a rien fait.
MirroredFate

3
Ha, ok, pour toute autre personne qui a ce problème, utilisez le chemin ci-dessus, sauf allez dans Bibliothèques plutôt que Divers et ajoutez le 'dl'
MirroredFate

2
Cette réponse a aidé. Pour tous ceux qui veulent trouver l'emplacement de libdl.so, allez simplement dans le répertoire racine et tapezlocate libdl.so
Nav

La réponse de MirroredFate a également fonctionné pour moi. Je ne comprends pas pourquoi, cependant; toutes les autres bibliothèques que j'ai jamais eu à lier fonctionnaient lorsqu'elles étaient placées dans Divers.
aggregate1166877

75

@Masci est correct, mais si vous utilisez C (et le gcccompilateur), tenez compte du fait que cela ne fonctionne pas:

gcc -ldl dlopentest.c

Mais cela fait:

gcc dlopentest.c -ldl

Il m'a fallu un peu de temps pour comprendre ...


2
J'ai trouvé que l'ordre des options compte aussi. Sur un projet utilisant sqlite3, je dois mettre -ldl (et -lpthread) après -lsqlite3. Je ne sais pas ce que c'est, je suis sûr que la réponse est là si je voulais juste RTFM.

Putain de merde, c'est tout! Je n'aurais jamais deviné que mettre les options en premier (ce qui a plus de sens pour moi) ne fonctionne pas, alors que les mettre après. Merci, @knocte!
Joe Strout

@ user2918461 a frappé le clou sur la tête. J'ai dû mettre les -l dans le "bon" ordre.
EMI du

oui, c'est bien d'avoir, mais pas une priorité pour écrire la réponse pour aider autant de personnes que possible en temps opportun
knocte

8

Le sujet est assez ancien, mais je me suis battu avec le même problème aujourd'hui lors de la compilation de cegui 0.7.1 (prérequis openVibe).

Ce qui a fonctionné pour moi était de mettre: LDFLAGS="-Wl,--no-as-needed" dans le Makefile.

J'ai aussi essayé -ldlde LDFLAGSmais en vain.


8

cela ne fonctionne pas:

gcc -ldl dlopentest.c

Mais cela fait:

gcc dlopentest.c -ldl

C'est une "fonctionnalité" ennuyeuse à coup sûr

J'avais du mal avec cela lors de l'écriture de la syntaxe heredoc et j'ai trouvé des faits intéressants . Avec CC=Clang, cela fonctionne:

$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

ainsi que tous ceux-ci:

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

Cependant, avec CC=gcc, seule la dernière variante fonctionne; -ldlafter -(le symbole d'argument stdin).


5

vous pouvez essayer d'ajouter ceci

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

vers les options de configuration


1
L'utilisation de la variable LIBS a fonctionné pour moi pour obtenir configure pour mettre -ldl au bon endroit sur la ligne de commande.
duncan le

5

J'utilisais CMake pour compiler mon projet et j'ai trouvé le même problème.

La solution décrite ici fonctionne comme un charme, ajoutez simplement $ {CMAKE_DL_LIBS} à l'appel target_link_libraries ()


1
Merci! Cela m'a aussi aidé. Mais seulement après avoir changé mon compilateur en clang SET(CMAKE_CXX_COMPILER /usr/bin/clang++). Avec / usr / bin / c ++ sur mon Ubuntu ça ne fonctionnait pas ... (voir aussi la réponse de
Vulcan Raven

3

Vous deviez faire quelque chose comme ça pour le makefile:

LDFLAGS='-ldl'
make install

Cela transmettra les indicateurs de l'éditeur de liens de make à l'éditeur de liens. Peu importe que le makefile ait été généré automatiquement.



1

Pour utiliser les fonctions dl, vous devez utiliser l'indicateur -ldl pour l'éditeur de liens.

comment faites-vous en éclipse?

Appuyez sur Projet -> Propriétés -> Construction C / C ++ -> Paramètres -> GCC C ++ Linker ->
Bibliothèques -> dans la zone "Bibliothèques (-l)" appuyez sur le signe "+" -> écrire " dl " (sans les guillemets) -> appuyez sur ok -> nettoyez et reconstruisez votre projet.


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

Une bonne description de l'importance du placement de -l dl

Mais il y a aussi une explication assez succincte dans la documentation 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.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.