关于在编译和链接C ++文件时的-ldl标志 [英] About the -ldl flag while compiling and linking C++ files

查看:115
本文介绍了关于在编译和链接C ++文件时的-ldl标志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参考以下代码

test_linker.cpp

int main() {

    srand(time(0));
    for (int i = 0; i < 10; ++i) {
        cout << rand() % 10 << endl;
    }

    return 0;
}

urandom.cpp

#include <iostream>
using std::cout;
using std::endl;
#include <dlfcn.h>

int rand() throw() {

    // get the original rand() function
    static auto original_rand = (decltype(&rand)) dlsym(RTLD_NEXT,"rand");

    cout << "Call made to rand()" << endl;
    return original_rand();
}

当我尝试使用以下命令编译代码

When I try to compile the code with the following command

g++ -std=c++11 -Wall -Werror -Wextra -Wvla -pedantic -O3 urandom.cpp -c
g++ -std=c++11 -Wall -O3 test_linker.cpp urandom.o -ldl

一切正常,但是当我将 -ldl 标志移到文件之前时,链接器抛出错误,提示

everything works fine, but when I move the -ldl flag to being before the files, the linker throws an error saying

urandom.cpp:(.text+0xaf): undefined reference to `dlsym'


$ b $的未定义引用b

问题1 ?有人可以解释为什么会这样吗?我通常不关心编译命令中标志的顺序。

Question 1 Could someone explain why this would happen? I generally do not care about the order of flags in a compilation command.

问题2 同样,将函数指针保持为原始 rand()函数一个静态变量?我不知道动态链接到底是如何工作的,恐怕函数地址可能会在运行时在内存中移动。手册页说带有 RTLD_NEXT 句柄的 dlsym()函数是一个昂贵的计算,所以我只是想偷懒评估一次。

Question 2 Also is it wrong to keep the function pointer to the original rand() function a static variable? I do not know how exactly dynamic linking works and I am afraid that maybe the function address is moved around in memory at runtime. The manual pages said that the dlsym() function with the RTLD_NEXT handle is an expensive computation so I just wanted to lazily evaluate this once.

注意:我正在Linux发行版上进行编译,并且涉及Linux动态链接器,因此我将继续在Linux上对其进行标记。

Note : I am compiling this on a Linux distribution and the Linux dynamic linker is involved so I will go ahead and tag this with Linux also.

推荐答案

-ldl 是链接程序的库名称。它告诉链接器查找并链接名为 libdl.so 的文件(有时也称为 libdl.a )。它的作用与在命令行的相同位置放置问题库的完整路径相同。

-ldl is a library designation for the linker. It tells the linker to find and link a file named libdl.so (or sometimes libdl.a). It has the same effect as placing a full path to the library in question in the same position of the command line.

命令行上的库和对象顺序确实很重要。通常,如果库A调用库B,则应在命令行中将B放在A之后。通常,所有库都应放在所有目标文件之后。 SO的一些问题和答案中对此进行了广泛的介绍,例如这一个

Library and object order on the command line does matter. Normally if library A calls library B, B should be placed after A on the command line. All libraries should normally go after all object files. This is covered extensively in several SO questions and answers like this one.

对于第二个问题,不,除非运行,否则函数的地址不会更改您 dlopen 共享库,然后将其卸载,然后再次 dlopen 。对于您而言,由于您没有 dlopen 库,因此可以安全地将函数地址保留在静态变量中。当然,如果您运行多个线程,则需要以某种方式确保线程安全(将其互斥或使用线程本地存储)。

As for the second question, no, an address of a function doesn't change at run time unless you dlopen a shared library, then unload it, then dlopen it again. In your case, since you don't dlopen the library, it is safe to keep the function address in a static variable. Of course if you run multiple threads you need to ensure thread safety somehow (mutex it out, or use thread-local storage).

这篇关于关于在编译和链接C ++文件时的-ldl标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆