【问题标题】:Linux c++ error: undefined reference to 'dlopen'Linux c++ 错误:未定义对“dlopen”的引用
【发布时间】:2010-10-31 16:41:12
【问题描述】:

我使用 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);
}

【问题讨论】:

    标签: c++ linux eclipse


    【解决方案1】:

    你必须链接libdl,添加

    -ldl

    到您的链接器选项

    【讨论】:

    • 我遇到了同样的问题...我在链接器标志文本字段中的项目>属性>C/C++Build>设置>(我的链接器)>杂项下添加了编译器标志。它什么也没做。
    • 哈,好的,对于其他有此问题的人,请使用上述路径,除了转到库而不是杂项并添加“dl”
    • 这个答案有帮助。对于任何想要找到 libdl.so 位置的人,只需转到根目录并输入 locate libdl.so
    • MirroredFate 的回答也对我有用。不过,我不明白为什么;我曾经必须链接的所有其他库在放置在杂项中时都有效。
    【解决方案2】:

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

    LDFLAGS='-ldl'
    make install
    

    这会将链接器标志从 make 传递到链接器。 makefile 是自动生成的并不重要。

    【讨论】:

      【解决方案3】:

      即使使用-ldl,我也遇到了同样的问题。

      除了这个选项,源文件需要放在库之前,见undefined reference to `dlopen'

      【讨论】:

        【解决方案4】:

        @Masci 是正确的,但如果您使用 C(和 gcc 编译器),请注意这不起作用:

        gcc -ldl dlopentest.c
        

        但这确实:

        gcc dlopentest.c -ldl
        

        花了我一点时间才弄明白...

        【讨论】:

        • 我发现选项的顺序也很重要。在使用 sqlite3 的项目中,我必须将 -ldl(和 -lpthread)放在 -lsqlite3 之后。不知道那是什么,如果我只是 RTFM,我相信答案就在那里。
        • 天哪,就是这样!我永远不会猜到将选项放在首位(这对我来说更有意义)是行不通的,而将它们放在后面却是行不通的。谢谢你,@knocte!
        • @user2918461 一针见血。我必须将 -l 放在“正确”的顺序中。
        • 这很有用
        【解决方案5】:

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

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

        我也试过-ldl 换成LDFLAGS,但无济于事。

        【讨论】:

          【解决方案6】:

          你可以尝试添加这个

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

          到配置选项

          【讨论】:

          • 使用 LIBS 变量对我有用,可以将 -ldl 放在命令行的正确位置。
          【解决方案7】:

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

          你在 eclipse 中是怎么做到的?

          Project --> Properties --> C/C++ build --> Settings -- > GCC C++ 链接器 -->
          --> 在“库(-l)”框中按“+”号->写“dl”(不带引号)->按ok --> 清理并重建您的项目。

          【讨论】:

            【解决方案8】:
             $gcc -o program program.c -l <library_to_resolve_program.c's_unresolved_symbols>
            

            A good description of why the placement of -l dl matters

            但是文档中也有一个非常简洁的解释 来自 $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.
            

            【讨论】:

              【解决方案9】:

              这不起作用:

              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 - &lt;&lt; EOF
              • $CC -x c -ldl -o app.exe - &lt;&lt; EOF
              • $CC -x c -o app.exe -ldl - &lt;&lt; EOF
              • $CC -x c -o app.exe - -ldl &lt;&lt; EOF

              但是,对于CC=gcc,只有最后一个变体有效; -ldl-(标准输入参数符号)之后。

              【讨论】:

              • 我也遇到过这样的问题。但我不知道为什么gcc dlopentest.c -ldl 有效而gcc -ldl dlopentest.c 无效。你怎么看?
              【解决方案10】:

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

              here 描述的解决方案就像一个魅力,只需将 ${CMAKE_DL_LIBS} 添加到 target_link_libraries() 调用

              【讨论】:

              • 谢谢!这对我也有帮助。但只有在我将编译器更改为 clang SET(CMAKE_CXX_COMPILER /usr/bin/clang++) 之后。在我的 Ubuntu 上使用 /usr/bin/c++ 无法正常工作...(另请参阅 vulcan raven 的回答)
              【解决方案11】:

              尝试使用标志no-threads 重建openssl(如果您正在与之链接)。

              然后尝试像这样链接:

              target_link_libraries(${project_name} dl pthread crypt m ${CMAKE_DL_LIBS})
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-02-20
                • 1970-01-01
                • 1970-01-01
                • 2020-07-21
                • 2012-10-10
                相关资源
                最近更新 更多