Linux C ++错误:未定义对“ dlopen”的引用


147

我使用C ++(Eclipse)在Linux中工作,并且想要使用一个库。Eclipse向我显示了一个错误:

undefined reference to 'dlopen' 

你知道解决方案吗?

这是我的代码:

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

Answers:


254

您必须针对libdl进行链接,添加

-ldl

到您的链接器选项


2
我遇到了同样的问题...我在“链接器标志”文本字段中的“项目”>“属性”>“ C / C ++ Build”>“设置”>“(我的链接器)”>“其他”下添加了编译器标志。它什么也没做。
MirroredFate 2013年

3
哈,好吧,对于其他有此问题的人,请使用上述路径,除了转到图书馆而不是其他地方,并添加“ dl”
MirroredFate 2013年

2
这个答案有所帮助。对于任何人谁想要找到libdl.so的位置,只要进入到根目录,然后键入locate libdl.so
导航

MirroredFate的答案也对我有用。我不明白为什么。当放置在Miscellaneous中时,我曾经必须链接的所有其他库都可以使用。
聚合

75

@Masci是正确的,但是如果您使用的是C(和gcc编译器),请考虑到这是行不通的:

gcc -ldl dlopentest.c

但这确实是:

gcc dlopentest.c -ldl

花了我一点时间来找出...


2
我发现选项的顺序也很重要。在使用sqlite3的项目中,我必须将-ldl(和-lpthread)放在-lsqlite3之后。不知道那是什么,我敢肯定,如果我只是RTFM,答案就在那里。

哎呀,就是这样!我永远都不会想到,将选项放在第一位(这对我来说更有意义)是行不通的,而将选项放在第二位是可行的。谢谢@knocte!
乔·斯特劳

@ user2918461击中了钉子。我不得不按“正确”的顺序放置-l。
NDEthos

是的,很高兴能获得帮助,但不是将要及时
写出

8

主题很老,但是今天我在编译cegui 0.7.1(openVibe先决条件)时遇到了同样的问题。

对我有用的是设置:LDFLAGS="-Wl,--no-as-needed" 在Makefile中。

我也曾尝试-ldlLDFLAGS但无济于事。


8

这不起作用:

gcc -ldl dlopentest.c

但这确实是:

gcc dlopentest.c -ldl

那肯定是一个令人讨厌的“功能”

在编写Heredoc语法时,我一直在努力,发现了一些有趣的事实。使用CC=Clang,这有效:

$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

以及所有这些:

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

但是,使用时CC=gcc,只有最后一个变体有效;-ldl之后-(stdin参数符号)。


5

您可以尝试添加此

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

到配置选项


1
使用LIBS变量对我有用,可以进行配置以将-ldl放在命令行的正确位置。
duncan 2015年

5

我使用CMake编译项目时,发现了相同的问题。

此处描述的解决方案就像一个超级按钮一样工作,只需将$ {CMAKE_DL_LIBS}添加到target_link_libraries()调用中


1
谢谢!这也对我有帮助。但是只有在我将编译器更改为clang之后SET(CMAKE_CXX_COMPILER /usr/bin/clang++)。在我的Ubuntu上使用/ usr / bin / c ++时,它无法工作...(另请参见vulcan raven的回答)
thomasfermi

3

您需要为makefile做这样的事情:

LDFLAGS='-ldl'
make install

这会将链接器标志从make传递到链接器。生成文件是自动生成的都没关系。



1

为了使用dl函数,您需要对链接器使用-ldl标志。

如何在日食中做到?

项目 -> 属性 -> C / C ++构建 -> 设置 -> GCC C ++链接器 ->
->在“库(-l)”框中,按“ +”号 ->编写“ dl ”(不带引号)->按OK- >清理并重建项目。


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

很好地说明了为什么-l dl的位置很重要

但是在$ 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.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.