Linux c ++ error: referensi tidak terdefinisi ke 'dlopen'

147

Saya bekerja di Linux dengan C ++ (Eclipse), dan ingin menggunakan perpustakaan. Eclipse menunjukkan saya kesalahan:

undefined reference to 'dlopen' 

Apakah Anda tahu solusinya?

Ini kode saya:

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

Jawaban:

254

Anda harus menautkan ke libdl, tambahkan

-ldl

ke opsi tautan Anda

Masci
sumber
2
Saya telah mengalami masalah yang sama ... Saya menambahkan flag compiler di bawah Project> Properties> C / C ++ Build> Settings> (My Linker)> Lain-lain di kolom teks flager Linker. Itu tidak melakukan apa pun.
MirroredFate
3
Ha, ok, untuk orang lain yang memiliki masalah ini, gunakan jalur di atas, kecuali pergi ke Libraries daripada Miscellaneous dan tambahkan 'dl'
MirroredFate
2
Jawaban ini membantu. Bagi siapa pun yang ingin menemukan lokasi libdl.so, cukup buka direktori root dan ketiklocate libdl.so
Nav
Jawaban MirroredFate berhasil juga untuk saya. Saya tidak mengerti mengapa; setiap perpustakaan lain yang pernah saya tautkan berfungsi saat ditempatkan di Miscellaneous.
aggregate1166877
75

@Masci benar, tetapi jika Anda menggunakan C (dan gcckompiler) memperhitungkan bahwa ini tidak berfungsi:

gcc -ldl dlopentest.c

Tetapi ini:

gcc dlopentest.c -ldl

Butuh saya sedikit untuk mencari tahu ...

knocte
sumber
2
Saya telah menemukan bahwa urutan opsi juga penting. Pada proyek yang menggunakan sqlite3, saya harus meletakkan -ldl (dan -lpthread) setelah -lsqlite3. Tidak tahu apa itu, saya yakin jawabannya ada di sana jika saya hanya RTFM.
Sial, itu dia! Saya tidak akan pernah menduga bahwa mengedepankan opsi (yang lebih masuk akal bagi saya) tidak berfungsi, sementara menempatkannya sesudahnya tidak berhasil. Terima kasih, @knocte!
Joe Strout
@ user2918461 membentur paku di kepala. Saya harus meletakkan -l dalam urutan "benar".
NDEthos
ya, menyenangkan untuk dimiliki, tetapi bukan prioritas untuk menulis jawaban untuk membantu sebanyak mungkin orang secara tepat waktu
knocte
8

Topiknya cukup lama, namun saya kesulitan dengan masalah yang sama hari ini saat mengkompilasi cegui 0.7.1 (prasyarat openVibe).

Apa yang berhasil bagi saya adalah mengatur: LDFLAGS="-Wl,--no-as-needed" di Makefile.

Saya juga mencoba -ldluntuk LDFLAGStetapi tidak berhasil.

bawey
sumber
8

ini tidak berfungsi:

gcc -ldl dlopentest.c

Tetapi ini:

gcc dlopentest.c -ldl

Itu pasti salah satu "fitur" yang mengganggu

Saya berjuang dengan itu ketika menulis sintaks heredoc dan menemukan beberapa fakta menarik . Dengan CC=Clang, ini berfungsi:

$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

dan juga semua ini:

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

Namun, dengan CC=gcc, hanya varian terakhir yang berfungsi; -ldlsetelah -(simbol argumen stdin).

gagak vulcan
sumber
5

Anda dapat mencoba menambahkan ini

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

ke opsi konfigurasi

pengguna2948547
sumber
1
Menggunakan variabel LIBS berhasil bagi saya untuk mendapatkan konfigurasi untuk menempatkan -ldl di tempat yang tepat pada baris perintah.
duncan
5

Saya menggunakan CMake untuk mengkompilasi proyek saya dan saya menemukan masalah yang sama.

Solusi yang dijelaskan di sini berfungsi seperti mantra, cukup tambahkan $ {CMAKE_DL_LIBS} ke panggilan target_link_libraries ()

Lucas Coelho
sumber
1
Terima kasih! Ini membantu saya juga. Tetapi hanya setelah saya mengubah kompiler saya menjadi dentang SET(CMAKE_CXX_COMPILER /usr/bin/clang++). Dengan / usr / bin / c ++ di Ubuntu saya itu tidak berfungsi ... (lihat juga jawaban gagak vulcan)
thomasfermi
3

Anda perlu melakukan sesuatu seperti ini untuk makefile:

LDFLAGS='-ldl'
make install

Itu akan melewati flag linker dari make through ke linker. Tidak masalah bahwa makefile dibuat secara otomatis.

rampok
sumber
1

Untuk menggunakan fungsi dl, Anda perlu menggunakan flag -ldl untuk linker.

bagaimana Anda melakukannya di gerhana?

Tekan Project -> Properties -> build C / C ++ -> Pengaturan -> GCC C ++ Linker ->
Libraries -> dalam kotak "Libraries (-l)" tekan tanda "+" -> tulis " dl " (tanpa tanda kutip) -> tekan ok -> bersihkan & bangun kembali proyek Anda.

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

Deskripsi yang baik tentang mengapa penempatan -l dl penting

Tapi ada juga penjelasan yang cukup ringkas di dokumen Dari $ 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
sumber