我怎么能LD_PRELOAD我自己编译的库?

时间:2016-02-11 02:48:13

标签: c linux gcc ld-preload

我想知道它是如何工作的,创建一个库并预加载它以便程序可以使用它而不是include语句中的那个。

这是我正在做的事情,到目前为止还没有工作。

//shared.cpp
int rand(){
    return 33;
}

//prograndom.cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(){
    srand(time(NULL));
    int i = 10;
    while(i--) printf("%d\n", rand()%100);
    return 0;
}

然后在终端:

$ gcc -shared -fPIC shared.cpp -o libshared.so
$ gcc prograndom.cpp -o prograndom
$ export LD_PRELOAD=/home/bob/desarrollo/libshared.so

最后

$ LD_PRELOAD=/home/bob/desarrollo/libshared.so ./prograndom

不打印33,只是随机数...

1 个答案:

答案 0 :(得分:7)

你的程序是C程序,但cpp文件扩展名意味着C ++,而GCC会以这种方式解释它。

这是一个问题,因为这意味着您的函数rand(在shared.cpp中)将被编译为C ++函数,其名称被修改为包含其类型签名。但是,在主要的#include <stdlib.h>中,它具有声明:

的效果
extern "C" int rand();

,这是链接器将查找的rand。所以你的PRELOAD将没有效果。

如果您将文件名从shared.cpp更改为shared.c,那么它将按预期工作。

其他具有可疑价值的替代方案是:

  • rand文件中声明extern "C"shared.cpp。然后,您可以将其编译为C ++。

  • 使用GCC选项-x c强制编译为C.