2016-02-11 42 views
1

我想知道这是如何工作的,创建一个库并预加载它,以便程序可以使用它而不是include语句中的一个。我怎样才能LD_PRELOAD我自己编译的库?

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

//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,只是随机数...

回答

7

你的程序是C程序,但cpp文件扩展名暗示C++,GCC将以这种方式解释它。

这是一个问题,因为这意味着您的函数rand(位于shared.cpp)将被编译为C++函数,其名称会被改为包含其类型签名。然而,其中有声明的效果主要你#include <stdlib.h>,:

extern "C" int rand(); 

那就是rand链接器将寻找。所以你的PRELOAD将不起作用。

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

其他替代价值令人怀疑的,分别是:

  • 声明rand在你的shared.cpp文件extern "C"。然后你可以将它编译为C++。

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

+0

非常感谢,它的工作! – HoNgOuRu

+0

如果我想在C++中做这个,我应该做些什么改变? – HoNgOuRu

+0

@HoNgOuRu:你必须声明你想用作'extern“C''的'rand',以匹配你试图覆盖的'rand'。但是如果你尝试使用编译为C的'main'的PRELOAD,那么你可能会遇到问题。 – rici