【发布时间】:2016-05-21 08:14:20
【问题描述】:
参考以下代码
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();
}
当我尝试使用以下命令编译代码时
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 标志移到文件之前时,链接器会抛出一个错误,提示
urandom.cpp:(.text+0xaf): undefined reference to `dlsym'
问题 1 有人能解释一下为什么会发生这种情况吗?我通常不关心编译命令中标志的顺序。
问题 2 另外,将指向原始rand() 函数的函数指针保留为静态变量是否有问题?我不知道动态链接究竟是如何工作的,我担心函数地址可能在运行时在内存中移动。手册页说带有RTLD_NEXT 句柄的dlsym() 函数是一项昂贵的计算,所以我只想懒惰地评估一次。
注意:我在 Linux 发行版上编译它,并且涉及到 Linux 动态链接器,所以我将继续用 Linux 标记它。
【问题讨论】:
-
-ldl 不仅仅是一个标志,它是一个库名称,命令行中库和目标文件的顺序很重要。
-
Q2:不,在静态中 kiip 并没有错(只要你是单线程的)。函数的地址在运行时不会改变。
-
如果你有时间,你能解释一下你的答案吗?
标签: c++ linux c++11 dynamic-linking