Erro Linux c ++: referência indefinida a 'dlopen'

147

Eu trabalho no Linux com C ++ (Eclipse) e quero usar uma biblioteca. O Eclipse me mostra um erro:

undefined reference to 'dlopen' 

Você conhece uma solução?

Aqui está o meu 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);
}
user101375
fonte

Respostas:

254

Você precisa vincular o libdl, adicionar

-ldl

às suas opções de vinculador

Masci
fonte
2
Eu encontrei o mesmo problema ... Adicionei o sinalizador do compilador em Projeto> Propriedades> Compilação C / C ++> Configurações> (Meu vinculador)> Diversos no campo de texto Sinalizadores do vinculador. Não fez nada.
precisa
3
Ha, ok, para qualquer outra pessoa que tem este problema, use o caminho acima, exceto ir para bibliotecas em vez de Diversos e adicione o 'dl'
MirroredFate
2
Esta resposta ajudou. Para quem quer encontrar a localização de libdl.so, basta ir para o diretório raiz e digitelocate libdl.so
Nav
A resposta de MirroredFate funcionou para mim também. Eu não entendo o porquê; todas as outras bibliotecas que já tive que vincular funcionaram quando colocadas em Diversos.
aggregate1166877
75

@Masci está correto, mas caso você esteja usando C (e o gcccompilador) leve em consideração que isso não funciona:

gcc -ldl dlopentest.c

Mas isso faz:

gcc dlopentest.c -ldl

Demorei um pouco para descobrir ...

knocte
fonte
2
Descobri que a ordem das opções também importa. Em um projeto usando sqlite3, tenho que colocar -ldl (e -lpthread) após -lsqlite3. Não sei o que é isso, tenho certeza que a resposta está lá se eu apenas RTFM.
Caramba, é isso! Eu nunca imaginaria que colocar as opções em primeiro lugar (o que faz mais sentido para mim) não funciona, enquanto colocá-las depois. Obrigado, @knocte!
21417 Joe Strout
@ user2918461 bateu na unha na cabeça. Eu tive que colocar os l na ordem "correta".
NDEthos 18/11/19
Sim, é bom ter, mas não é uma prioridade escrever a resposta para ajudar o maior número possível de pessoas em tempo hábil #
knocte
8

O tópico é bastante antigo, mas lutei com o mesmo problema hoje ao compilar o cegui 0.7.1 (pré-requisito do openVibe).

O que funcionou para mim foi definir: LDFLAGS="-Wl,--no-as-needed" no Makefile.

Eu também tentei -ldlpara LDFLAGS, mas sem sucesso.

bawey
fonte
8

isso não funciona:

gcc -ldl dlopentest.c

Mas isso faz:

gcc dlopentest.c -ldl

Esse é um "recurso" irritante, com certeza

Eu estava enfrentando dificuldades ao escrever a sintaxe heredoc e encontrei alguns fatos interessantes . Com CC=Clang, isso 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

bem como todos estes:

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

No entanto, com CC=gcc, apenas a última variante funciona; -ldlafter -(o símbolo do argumento stdin).

corvo vulcano
fonte
5

você pode tentar adicionar isso

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

para as opções de configuração

user2948547
fonte
1
O uso da variável LIBS funcionou para que eu conseguisse configurar o putldl no lugar certo na linha de comando.
duncan
5

Eu estava usando o CMake para compilar meu projeto e encontrei o mesmo problema.

A solução descrita aqui funciona como um encanto, basta adicionar $ {CMAKE_DL_LIBS} à chamada target_link_libraries ()

Lucas Coelho
fonte
1
Obrigado! Isso me ajudou também. Mas somente depois que mudei meu compilador para clang SET(CMAKE_CXX_COMPILER /usr/bin/clang++). Com / usr / bin / c ++ no meu Ubuntu não estava funcionando ... (ver também resposta do Corvo Vulcan)
thomasfermi
3

Você precisava fazer algo assim para o makefile:

LDFLAGS='-ldl'
make install

Isso passará os sinalizadores do vinculador do make até o vinculador. Não importa que o makefile tenha sido gerado automaticamente.

Roubar
fonte
1

Eu encontrei o mesmo problema, mesmo usando -ldl.

Além dessa opção, os arquivos de origem precisam ser colocados antes das bibliotecas; consulte a referência indefinida ao `dlopen ' .

Deqing
fonte
1

Para usar as funções dl, você precisa usar o sinalizador -ldl para o vinculador.

como você faz isso no eclipse?

Pressione Projeto -> Propriedades -> Compilação C / C ++ -> Configurações -> Linker do GCC C ++ ->
Bibliotecas -> na caixa "Bibliotecas (-l)" e pressione o sinal "+" -> gravação " dl " (sem as aspas) -> pressione ok -> limpe e reconstrua seu projeto.

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

Uma boa descrição de por que o posicionamento de -l dl é importante

Mas também há uma explicação bastante sucinta nos documentos 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
fonte