这是我的第一篇文章!我已经实现了一个小的C ++程序,该程序使用foo实现作为共享库。共享库包含两个功能:get_number()
和print_text()
。
目标是拦截器库(共享库)更改foo库的功能,这样
get_number()
应该替换为始终返回333的函数。print_text()
应该换行,以便在执行原始功能之前和之后打印一些文本。源代码如下:
foo.hpp
#ifndef _FOO_HPP
#define _FOO_HPP
namespace foo {
int get_number();
void print_text();
}
#endif
foo.cpp
#include "foo.hpp"
#include <iostream>
namespace foo {
int get_number()
{
return 13;
}
void print_text()
{
std::cout << "Hello World!" << std::endl;
}
}
interceptor.hpp
#ifndef _INTERCEPTOR_HPP
#define _INTERCEPTOR_HPP
#include <iostream>
namespace interceptor {
int get_number();
void print_text();
}
#endif
interceptor.cpp
#include "interceptor.hpp"
namespace interceptor {
int get_number()
{
return 333;
}
void print_text()
{
// Print here some text.
std::cout << "Hello World!" << std::endl;
// Print here some test.
}
}
main.cpp
#include <iostream>
#include "foo.hpp"
int main(void)
{
std::cout << "Number: " << foo::get_number() << "\n" << std::endl;
foo::print_text();
return 0;
}
在有和没有拦截器库的情况下运行主可执行程序可能看起来像这样:
$ ./main
Number: 13
Hello World!
$ LD_PRELOAD=$PWD/interceptor.so ./main
Number: 333
Hi before
Hello World!
Bye after
我是共享库和拦截器库中的初学者。
我希望有人可以帮助我解决我的问题。
将main.o
与foo.so
链接在一起,例如:
g++ -o main main.o foo.so
如果您尝试运行
./main
您会得到一个错误,因为foo.so
不在动态链接程序查找它的系统库路径中。我们也可以告诉它在当前文件夹中查找:
$ LD_LIBRARY_PATH=. ./main
Number: 13
Hello World!
现在带有interceptor.so
:
$ LD_LIBRARY_PATH=. LD_PRELOAD=$PWD/interceptor.so ./main
Number: 13
Hello World!
您可以看到没有任何变化。这是因为您的interceptor.so
实际上没有包含foo::get_number
和foo::print_text
的定义。它包含interceptor::get_number
和interceptor::print_text
的定义,但是main
永远不会调用它们!
[interceptor.cpp
应该实现与foo.cpp
相同的功能,因此在将namespace interceptor
替换为namespace foo
并重新编译之后:
$ LD_LIBRARY_PATH=. LD_PRELOAD=$PWD/interceptor.so ./main
Number: 333
Hello World!