Error de Linux c ++: referencia indefinida a 'dlopen'

147

Trabajo en Linux con C ++ (Eclipse) y quiero usar una biblioteca. Eclipse me muestra un error:

undefined reference to 'dlopen' 

¿Conoces una solución?

Aquí está mi código:

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

Respuestas:

254

Tienes que vincular contra libdl, agregar

-ldl

a sus opciones de enlazador

Masci
fuente
2
Me he encontrado con el mismo problema ... Agregué el indicador del compilador en Proyecto> Propiedades> Compilación C / C ++> Configuración> (Mi vinculador)> Varios en el campo de texto de indicadores del vinculador. No hizo nada
MirroredFate
3
Ja, ok, para cualquier otra persona que tenga este problema, use la ruta anterior, excepto ir a Bibliotecas en lugar de Varios y agregue el 'dl'
MirroredFate
2
Esta respuesta ayudó. Para cualquiera que quiera encontrar la ubicación de libdl.so, solo vaya al directorio raíz y escribalocate libdl.so
Nav
La respuesta de MirroredFate también funcionó para mí. Sin embargo, no entiendo por qué; todas las demás bibliotecas que he tenido que vincular funcionan cuando se colocan en Varios.
agregado1166877
75

@Masci es correcto, pero en caso de que esté utilizando C (y el gcccompilador) tenga en cuenta que esto no funciona:

gcc -ldl dlopentest.c

Pero esto hace:

gcc dlopentest.c -ldl

Me tomó un poco descubrirlo ...

knocte
fuente
2
Descubrí que el orden de las opciones también es importante. En un proyecto que usa sqlite3, tengo que poner -ldl (y -lpthread) después de -lsqlite3. No sé qué es eso, estoy seguro de que la respuesta está ahí si solo quisiera RTFM.
Santa mierda, eso es todo! Nunca hubiera imaginado que poner las opciones primero (lo que tiene más sentido para mí) no funciona, mientras que ponerlas después sí lo hace. Gracias, @knocte!
Joe Strout
@ user2918461 golpeó el clavo en la cabeza. Tuve que poner las -l en el orden "correcto".
NDEthos
Sí, es agradable tener, pero no es una prioridad para escribir la respuesta para ayudar a tantas personas como sea posible en el momento oportuno
knocte
8

El tema es bastante antiguo, sin embargo, luché con el mismo problema hoy mientras compilaba cegui 0.7.1 (requisito previo de openVibe).

Lo que funcionó para mí fue establecer: LDFLAGS="-Wl,--no-as-needed" en el Makefile.

También he intentado -ldlpara LDFLAGSpero fue en vano.

bawey
fuente
8

esto no funciona:

gcc -ldl dlopentest.c

Pero esto hace:

gcc dlopentest.c -ldl

Esa es una "característica" molesta con seguridad

Estaba luchando con eso cuando escribía la sintaxis heredoc y encontré algunos datos interesantes . Con CC=Clangesto funciona:

$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

así como todos estos:

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

Sin embargo, con CC=gcc, solo funciona la última variante; -ldldespués -(el símbolo de argumento stdin).

cuervo vulcano
fuente
5

puedes intentar agregar esto

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

a las opciones de configuración

usuario2948547
fuente
1
El uso de la variable LIBS me funcionó para configurar a poner -ldl en el lugar correcto en la línea de comando.
Duncan
5

Estaba usando CMake para compilar mi proyecto y encontré el mismo problema.

La solución descrita aquí funciona de maravilla, simplemente agregue $ {CMAKE_DL_LIBS} a la llamada target_link_libraries ()

Lucas Coelho
fuente
1
¡Gracias! Esto también me ayudó. Pero solo después de que cambié mi compilador a clang SET(CMAKE_CXX_COMPILER /usr/bin/clang++). Con / usr / bin / c ++ en mi Ubuntu no funcionaba ... (ver también la respuesta de vulcan raven)
thomasfermi
3

Necesitabas hacer algo así para el archivo MAKE:

LDFLAGS='-ldl'
make install

Eso pasará las banderas del enlazador de make al enlazador. No importa que el archivo MAKE se haya generado automáticamente.

Robar
fuente
1

Me encontré con el mismo problema incluso usando -ldl .

Además de esta opción, los archivos de origen deben colocarse antes de las bibliotecas, consulte la referencia indefinida a 'dlopen' .

Deqing
fuente
1

Para usar las funciones dl, debe usar el indicador -ldl para el enlazador.

¿Cómo lo haces en eclipse?

Presione Proyecto -> Propiedades -> C / C ++ build -> Configuración -> GCC C ++ Linker ->
Bibliotecas -> en el cuadro "Bibliotecas (-l)" presione el signo "+" -> escribir " dl " (sin las comillas) -> presione ok -> limpiar y reconstruir su proyecto.

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

Una buena descripción de por qué es importante la ubicación de -l dl

Pero también hay una explicación bastante sucinta en los documentos. Desde $ 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
fuente