Linux c ++ hatası: 'dlopen'e tanımsız başvuru


156

Linux'ta C ++ (Eclipse) ile çalışıyorum ve bir kitaplık kullanmak istiyorum. Eclipse bana bir hata gösteriyor:

undefined reference to 'dlopen' 

Bir çözüm biliyor musun?

İşte kodum:

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

Yanıtlar:


264

Libdl ile bağlantı kurmalısınız, ekleyin

-ldl

bağlayıcı seçeneklerinize


2
Aynı problemle karşılaştım ... Derleyici bayrağını Proje> Özellikler> C / C ++ Oluşturma> Ayarlar> (Bağlayıcım)> Çeşitli altındaki Bağlayıcı bayrakları metin alanına ekledim. Hiçbir şey yapmadı.
MirroredFate

3
Ha, tamam, bu soruna sahip olan herkes için, Miscellaneous yerine Kitaplıklar'a gitme ve "dl"
MirroredFate

2
Bu cevap yardımcı oldu. Libdl.so'nun yerini bulmak isteyenler için, kök dizine gidin ve şunu yazınlocate libdl.so
Nav

MirroredFate'in cevabı benim için de çalıştı. Yine de nedenini anlamıyorum; Bağlamak zorunda kaldığım diğer tüm kitaplıklar, Miscellaneous'a yerleştirildiğinde çalıştı.
aggregate1166877

77

@Masci haklı, ancak C (ve gccderleyici) kullanıyorsanız , bunun işe yaramadığını hesaba katın :

gcc -ldl dlopentest.c

Ancak bu:

gcc dlopentest.c -ldl

Anlamam biraz zaman aldı ...


2
Seçeneklerin sırasının da önemli olduğunu buldum. Sqlite3 kullanan bir projede, -lsqlite3'ten sonra -ldl (ve -lpthread) koymam gerekiyor. Bunun ne olduğunu bilmiyorum, sadece RTFM yapsaydım cevabın orada olduğuna eminim.

Vay canına, işte bu! Seçenekleri ilk sıraya koymanın (ki bu benim için daha mantıklı) işe yaramayacağını asla tahmin edemezdim. Teşekkürler @knocte!
Joe Strout

@ user2918461 baştaki çiviyi vurdu. -L'leri "doğru" sıraya koymak zorunda kaldım.
NDEthos

evet, olması güzel, ancak cevabı olabildiğince çok insana zamanında yardımcı olmak için yazma önceliği değil
2019'da

8

Konu oldukça eski, ancak bugün cegui 0.7.1'i derlerken aynı sorunla uğraştım (openVibe ön koşulu).

Benim için işe LDFLAGS="-Wl,--no-as-needed" yarayan şey ayarlamak oldu: Makefile'da.

Ben de denedim -ldliçin LDFLAGSama boşuna.


8

bu çalışmıyor:

gcc -ldl dlopentest.c

Ancak bu:

gcc dlopentest.c -ldl

Bu kesinlikle sinir bozucu bir "özellik"

Yorumlu söz dizimi yazarken bununla mücadele ediyordum ve bazı ilginç gerçekler buldum . İle CC=Clangbu çalışır:

$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

yanı sıra bunların tümü:

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

Ancak, CC=gccyalnızca son değişken çalışır; -ldlafter -(stdin argüman sembolü).


7

Projemi derlemek için CMake kullanıyordum ve aynı sorunu buldum.

Burada açıklanan çözüm bir cazibe gibi çalışır, target_link_libraries () çağrısına $ {CMAKE_DL_LIBS} eklemeniz yeterlidir


1
Teşekkürler! Bu bana da yardımcı oldu. Ama ancak derleyicimi clang olarak değiştirdikten sonra SET(CMAKE_CXX_COMPILER /usr/bin/clang++).
Ubuntu'mda

5

bunu eklemeyi deneyebilirsin

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

yapılandırma seçeneklerine


1
LIBS değişkenini kullanmak, komut satırında -ldl'yi doğru yere koymak için yapılandırmam için çalıştı.
duncan

3

Makefile için buna benzer bir şey yapmanız gerekiyordu:

LDFLAGS='-ldl'
make install

Bu, bağlayıcı bayraklarını make through'dan bağlayıcıya geçirir. Makefile'ın otomatik olarak oluşturulmuş olması önemli değil.



1

Dl işlevlerini kullanmak için bağlayıcı için -ldl bayrağını kullanmanız gerekir.

tutulmada bunu nasıl yaparsın?

Basın Projesi -> Özellikler -> C / C ++ build -> Ayarlar -> GCC C ++ Linker ->
Kütüphaneler -> "Kütüphaneler (-l)" kutusunda basın "+" işareti -> yazma " dl (tırnaklar olmadan)" -> basın ok -> & temiz yeniden projenizi.


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

-L dl'nin yerleştirilmesinin neden önemli olduğuna dair iyi bir açıklama

Ancak dokümanlarda oldukça kısa ve öz bir açıklama da var 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.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.